49
49
50
50
#include " llvm/ADT/STLExtras.h"
51
51
#include " llvm/BinaryFormat/Dwarf.h"
52
- #include " llvm/ExecutionEngine/Orc/Core.h"
53
- #include " llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
54
- #include " llvm/ExecutionEngine/Orc/LLJIT.h"
52
+ #include " llvm/ExecutionEngine/MCJIT.h"
53
+ #include " llvm/ExecutionEngine/SectionMemoryManager.h"
55
54
#include " llvm/IR/DataLayout.h"
56
55
#include " llvm/IR/DerivedTypes.h"
57
56
#include " llvm/IR/IRBuilder.h"
85
84
#define USE_GLOBAL_STR_CONSTS true
86
85
#endif
87
86
88
- llvm::ExitOnError ExitOnErr;
89
-
90
87
//
91
88
// Example types
92
89
//
@@ -145,7 +142,6 @@ static llvm::ConstantInt *ourExceptionCaughtState;
145
142
146
143
typedef std::vector<std::string> ArgNames;
147
144
typedef std::vector<llvm::Type*> ArgTypes;
148
- typedef llvm::ArrayRef<llvm::Type *> TypeArray;
149
145
150
146
//
151
147
// Code Generation Utilities
@@ -896,10 +892,13 @@ void generateStringPrint(llvm::LLVMContext &context,
896
892
// / generated, and is used to hold the constant string. A value of
897
893
// / false indicates that the constant string will be stored on the
898
894
// / stack.
899
- void generateIntegerPrint (llvm::LLVMContext &context, llvm::Module &module ,
895
+ void generateIntegerPrint (llvm::LLVMContext &context,
896
+ llvm::Module &module ,
900
897
llvm::IRBuilder<> &builder,
901
- llvm::Function &printFunct, llvm::Value *toPrint,
902
- std::string format, bool useGlobal = true ) {
898
+ llvm::Function &printFunct,
899
+ llvm::Value &toPrint,
900
+ std::string format,
901
+ bool useGlobal = true ) {
903
902
llvm::Constant *stringConstant =
904
903
llvm::ConstantDataArray::getString (context, format);
905
904
llvm::Value *stringVar;
@@ -921,9 +920,10 @@ void generateIntegerPrint(llvm::LLVMContext &context, llvm::Module &module,
921
920
922
921
llvm::Value *cast = builder.CreateBitCast (stringVar,
923
922
builder.getPtrTy ());
924
- builder.CreateCall (&printFunct, {toPrint, cast});
923
+ builder.CreateCall (&printFunct, {& toPrint, cast});
925
924
}
926
925
926
+
927
927
// / Generates code to handle finally block type semantics: always runs
928
928
// / regardless of whether a thrown exception is passing through or the
929
929
// / parent function is simply exiting. In addition to printing some state
@@ -997,10 +997,10 @@ static llvm::BasicBlock *createFinallyBlock(llvm::LLVMContext &context,
997
997
bufferToPrint.str (),
998
998
USE_GLOBAL_STR_CONSTS);
999
999
1000
- llvm::SwitchInst *theSwitch = builder.CreateSwitch (
1001
- builder. CreateLoad (ourExceptionNotThrownState-> getType ( ),
1002
- *exceptionCaughtFlag) ,
1003
- &terminatorBlock, 2 );
1000
+ llvm::SwitchInst *theSwitch = builder.CreateSwitch (builder. CreateLoad (
1001
+ *exceptionCaughtFlag ),
1002
+ &terminatorBlock ,
1003
+ 2 );
1004
1004
theSwitch->addCase (ourExceptionCaughtState, &terminatorBlock);
1005
1005
theSwitch->addCase (ourExceptionThrownState, &unwindResumeBlock);
1006
1006
@@ -1186,7 +1186,7 @@ static llvm::Function *createCatchWrappedInvokeFunction(
1186
1186
1187
1187
// Note: function handles NULL exceptions
1188
1188
builder.CreateCall (deleteOurException,
1189
- builder.CreateLoad (builder. getPtrTy (), exceptionStorage));
1189
+ builder.CreateLoad (exceptionStorage));
1190
1190
builder.CreateRetVoid ();
1191
1191
1192
1192
// Normal Block
@@ -1206,8 +1206,7 @@ static llvm::Function *createCatchWrappedInvokeFunction(
1206
1206
1207
1207
builder.SetInsertPoint (unwindResumeBlock);
1208
1208
1209
- builder.CreateResume (
1210
- builder.CreateLoad (ourCaughtResultType, caughtResultStorage));
1209
+ builder.CreateResume (builder.CreateLoad (caughtResultStorage));
1211
1210
1212
1211
// Exception Block
1213
1212
@@ -1242,9 +1241,8 @@ static llvm::Function *createCatchWrappedInvokeFunction(
1242
1241
// Retrieve exception_class member from thrown exception
1243
1242
// (_Unwind_Exception instance). This member tells us whether or not
1244
1243
// the exception is foreign.
1245
- llvm::Value *unwindExceptionClass = builder.CreateLoad (
1246
- builder.getInt64Ty (),
1247
- builder.CreateStructGEP (
1244
+ llvm::Value *unwindExceptionClass =
1245
+ builder.CreateLoad (builder.CreateStructGEP (
1248
1246
ourUnwindExceptionType,
1249
1247
builder.CreatePointerCast (unwindException,
1250
1248
ourUnwindExceptionType->getPointerTo ()),
@@ -1280,9 +1278,9 @@ static llvm::Function *createCatchWrappedInvokeFunction(
1280
1278
//
1281
1279
// Note: ourBaseFromUnwindOffset is usually negative
1282
1280
llvm::Value *typeInfoThrown = builder.CreatePointerCast (
1283
- builder.CreateConstGEP1_64 (builder. getPtrTy (), unwindException,
1284
- ourBaseFromUnwindOffset),
1285
- ourExceptionType->getPointerTo ());
1281
+ builder.CreateConstGEP1_64 (unwindException,
1282
+ ourBaseFromUnwindOffset),
1283
+ ourExceptionType->getPointerTo ());
1286
1284
1287
1285
// Retrieve thrown exception type info type
1288
1286
//
@@ -1291,15 +1289,17 @@ static llvm::Function *createCatchWrappedInvokeFunction(
1291
1289
typeInfoThrown = builder.CreateStructGEP (ourExceptionType, typeInfoThrown, 0 );
1292
1290
1293
1291
llvm::Value *typeInfoThrownType =
1294
- builder.CreateStructGEP (ourTypeInfoType , typeInfoThrown, 0 );
1292
+ builder.CreateStructGEP (builder. getPtrTy () , typeInfoThrown, 0 );
1295
1293
1296
- llvm::Value *ti8 =
1297
- builder.CreateLoad (builder.getInt8Ty (), typeInfoThrownType);
1298
- generateIntegerPrint (context, module , builder, *toPrint32Int,
1299
- builder.CreateZExt (ti8, builder.getInt32Ty ()),
1294
+ generateIntegerPrint (context,
1295
+ module ,
1296
+ builder,
1297
+ *toPrint32Int,
1298
+ *(builder.CreateLoad (typeInfoThrownType)),
1300
1299
" Gen: Exception type <%d> received (stack unwound) "
1301
1300
" in " +
1302
- ourId + " .\n " ,
1301
+ ourId +
1302
+ " .\n " ,
1303
1303
USE_GLOBAL_STR_CONSTS);
1304
1304
1305
1305
// Route to matched type info catch block or run cleanup finally block
@@ -1311,7 +1311,8 @@ static llvm::Function *createCatchWrappedInvokeFunction(
1311
1311
1312
1312
for (unsigned i = 1 ; i <= numExceptionsToCatch; ++i) {
1313
1313
nextTypeToCatch = i - 1 ;
1314
- switchToCatchBlock->addCase (llvm::ConstantInt::get (builder.getInt32Ty (), i),
1314
+ switchToCatchBlock->addCase (llvm::ConstantInt::get (
1315
+ llvm::Type::getInt32Ty (context), i),
1315
1316
catchBlocks[nextTypeToCatch]);
1316
1317
}
1317
1318
@@ -1386,10 +1387,14 @@ createThrowExceptionFunction(llvm::Module &module, llvm::IRBuilder<> &builder,
1386
1387
builder.SetInsertPoint (entryBlock);
1387
1388
1388
1389
llvm::Function *toPrint32Int = module .getFunction (" print32Int" );
1389
- generateIntegerPrint (context, module , builder, *toPrint32Int,
1390
- builder.CreateZExt (exceptionType, builder.getInt32Ty ()),
1391
- " \n Gen: About to throw exception type <%d> in " + ourId +
1392
- " .\n " ,
1390
+ generateIntegerPrint (context,
1391
+ module ,
1392
+ builder,
1393
+ *toPrint32Int,
1394
+ *exceptionType,
1395
+ " \n Gen: About to throw exception type <%d> in " +
1396
+ ourId +
1397
+ " .\n " ,
1393
1398
USE_GLOBAL_STR_CONSTS);
1394
1399
1395
1400
// Switches on runtime type info type value to determine whether or not
@@ -1541,13 +1546,15 @@ typedef void (*OurExceptionThrowFunctType) (int32_t typeToThrow);
1541
1546
// / @param function generated test function to run
1542
1547
// / @param typeToThrow type info type of generated exception to throw, or
1543
1548
// / indicator to cause foreign exception to be thrown.
1544
- static void runExceptionThrow (llvm::orc::LLJIT *JIT, std::string function,
1545
- int32_t typeToThrow) {
1549
+ static
1550
+ void runExceptionThrow (llvm::ExecutionEngine *engine,
1551
+ llvm::Function *function,
1552
+ int32_t typeToThrow) {
1546
1553
1547
1554
// Find test's function pointer
1548
1555
OurExceptionThrowFunctType functPtr =
1549
- reinterpret_cast <OurExceptionThrowFunctType>( reinterpret_cast < uintptr_t >(
1550
- ExitOnErr (JIT-> lookup (function)). getValue ( )));
1556
+ reinterpret_cast <OurExceptionThrowFunctType>(
1557
+ reinterpret_cast < intptr_t >(engine-> getPointerToFunction (function)));
1551
1558
1552
1559
try {
1553
1560
// Run test
@@ -1576,6 +1583,8 @@ static void runExceptionThrow(llvm::orc::LLJIT *JIT, std::string function,
1576
1583
// End test functions
1577
1584
//
1578
1585
1586
+ typedef llvm::ArrayRef<llvm::Type*> TypeArray;
1587
+
1579
1588
// / This initialization routine creates type info globals and
1580
1589
// / adds external function declarations to module.
1581
1590
// / @param numTypeInfos number of linear type info associated type info types
@@ -1885,73 +1894,93 @@ int main(int argc, char *argv[]) {
1885
1894
return (0 );
1886
1895
}
1887
1896
1897
+ // If not set, exception handling will not be turned on
1898
+ llvm::TargetOptions Opts;
1899
+
1888
1900
llvm::InitializeNativeTarget ();
1889
1901
llvm::InitializeNativeTargetAsmPrinter ();
1890
- auto Context = std::make_unique< llvm::LLVMContext>() ;
1891
- llvm::IRBuilder<> theBuilder (* Context);
1902
+ llvm::LLVMContext Context ;
1903
+ llvm::IRBuilder<> theBuilder (Context);
1892
1904
1893
1905
// Make the module, which holds all the code.
1894
1906
std::unique_ptr<llvm::Module> Owner =
1895
- std::make_unique<llvm::Module>(" my cool jit" , * Context);
1907
+ std::make_unique<llvm::Module>(" my cool jit" , Context);
1896
1908
llvm::Module *module = Owner.get ();
1897
1909
1898
- // Build LLJIT
1899
- std::unique_ptr<llvm::orc::LLJIT> JIT =
1900
- ExitOnErr (llvm::orc::LLJITBuilder ().create ());
1910
+ std::unique_ptr<llvm::RTDyldMemoryManager> MemMgr (new llvm::SectionMemoryManager ());
1901
1911
1902
- // Set up the optimizer pipeline.
1903
- llvm::legacy::FunctionPassManager fpm (module );
1912
+ // Build engine with JIT
1913
+ llvm::EngineBuilder factory (std::move (Owner));
1914
+ factory.setEngineKind (llvm::EngineKind::JIT);
1915
+ factory.setTargetOptions (Opts);
1916
+ factory.setMCJITMemoryManager (std::move (MemMgr));
1917
+ llvm::ExecutionEngine *executionEngine = factory.create ();
1904
1918
1905
- // Optimizations turned on
1919
+ {
1920
+ llvm::legacy::FunctionPassManager fpm (module );
1921
+
1922
+ // Set up the optimizer pipeline.
1923
+ // Start with registering info about how the
1924
+ // target lays out data structures.
1925
+ module ->setDataLayout (executionEngine->getDataLayout ());
1926
+
1927
+ // Optimizations turned on
1906
1928
#ifdef ADD_OPT_PASSES
1907
1929
1908
- // Basic AliasAnslysis support for GVN.
1909
- fpm.add (llvm::createBasicAliasAnalysisPass ());
1930
+ // Basic AliasAnslysis support for GVN.
1931
+ fpm.add (llvm::createBasicAliasAnalysisPass ());
1910
1932
1911
- // Promote allocas to registers.
1912
- fpm.add (llvm::createPromoteMemoryToRegisterPass ());
1933
+ // Promote allocas to registers.
1934
+ fpm.add (llvm::createPromoteMemoryToRegisterPass ());
1913
1935
1914
- // Do simple "peephole" optimizations and bit-twiddling optzns.
1915
- fpm.add (llvm::createInstructionCombiningPass ());
1936
+ // Do simple "peephole" optimizations and bit-twiddling optzns.
1937
+ fpm.add (llvm::createInstructionCombiningPass ());
1916
1938
1917
- // Reassociate expressions.
1918
- fpm.add (llvm::createReassociatePass ());
1939
+ // Reassociate expressions.
1940
+ fpm.add (llvm::createReassociatePass ());
1919
1941
1920
- // Eliminate Common SubExpressions.
1921
- fpm.add (llvm::createGVNPass ());
1942
+ // Eliminate Common SubExpressions.
1943
+ fpm.add (llvm::createGVNPass ());
1922
1944
1923
- // Simplify the control flow graph (deleting unreachable
1924
- // blocks, etc).
1925
- fpm.add (llvm::createCFGSimplificationPass ());
1945
+ // Simplify the control flow graph (deleting unreachable
1946
+ // blocks, etc).
1947
+ fpm.add (llvm::createCFGSimplificationPass ());
1926
1948
#endif // ADD_OPT_PASSES
1927
1949
1928
- fpm.doInitialization ();
1950
+ fpm.doInitialization ();
1929
1951
1930
- // Generate test code using function throwCppException(...) as
1931
- // the function which throws foreign exceptions.
1932
- createUnwindExceptionTest (*module , theBuilder, fpm, " throwCppException" );
1952
+ // Generate test code using function throwCppException(...) as
1953
+ // the function which throws foreign exceptions.
1954
+ llvm::Function *toRun =
1955
+ createUnwindExceptionTest (*module ,
1956
+ theBuilder,
1957
+ fpm,
1958
+ " throwCppException" );
1933
1959
1934
- ExitOnErr (JIT->addIRModule (
1935
- llvm::orc::ThreadSafeModule (std::move (Owner), std::move (Context))));
1960
+ executionEngine->finalizeObject ();
1936
1961
1937
1962
#ifndef NDEBUG
1938
- fprintf (stderr, " \n Begin module dump:\n\n " );
1963
+ fprintf (stderr, " \n Begin module dump:\n\n " );
1939
1964
1940
- module ->print ( llvm::errs (), nullptr );
1965
+ module ->dump ( );
1941
1966
1942
- fprintf (stderr, " \n End module dump:\n " );
1967
+ fprintf (stderr, " \n End module dump:\n " );
1943
1968
#endif
1944
1969
1945
- fprintf (stderr, " \n\n Begin Test:\n " );
1946
- std::string toRun = " outerCatchFunct" ;
1970
+ fprintf (stderr, " \n\n Begin Test:\n " );
1971
+
1972
+ for (int i = 1 ; i < argc; ++i) {
1973
+ // Run test for each argument whose value is the exception
1974
+ // type to throw.
1975
+ runExceptionThrow (executionEngine,
1976
+ toRun,
1977
+ (unsigned ) strtoul (argv[i], NULL , 10 ));
1978
+ }
1947
1979
1948
- for (int i = 1 ; i < argc; ++i) {
1949
- // Run test for each argument whose value is the exception
1950
- // type to throw.
1951
- runExceptionThrow (JIT.get (), toRun, (unsigned )strtoul (argv[i], NULL , 10 ));
1980
+ fprintf (stderr, " \n End Test:\n\n " );
1952
1981
}
1953
1982
1954
- fprintf (stderr, " \n End Test: \n\n " ) ;
1983
+ delete executionEngine ;
1955
1984
1956
1985
return 0 ;
1957
1986
}
0 commit comments