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