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
@@ -891,13 +895,10 @@ void generateStringPrint(llvm::LLVMContext &context,
891
895
// / generated, and is used to hold the constant string. A value of
892
896
// / false indicates that the constant string will be stored on the
893
897
// / stack.
894
- void generateIntegerPrint (llvm::LLVMContext &context,
895
- llvm::Module &module ,
898
+ void generateIntegerPrint (llvm::LLVMContext &context, llvm::Module &module ,
896
899
llvm::IRBuilder<> &builder,
897
- llvm::Function &printFunct,
898
- llvm::Value &toPrint,
899
- std::string format,
900
- bool useGlobal = true ) {
900
+ llvm::Function &printFunct, llvm::Value *toPrint,
901
+ std::string format, bool useGlobal = true ) {
901
902
llvm::Constant *stringConstant =
902
903
llvm::ConstantDataArray::getString (context, format);
903
904
llvm::Value *stringVar;
@@ -919,10 +920,9 @@ void generateIntegerPrint(llvm::LLVMContext &context,
919
920
920
921
llvm::Value *cast = builder.CreateBitCast (stringVar,
921
922
builder.getPtrTy ());
922
- builder.CreateCall (&printFunct, {& toPrint, cast});
923
+ builder.CreateCall (&printFunct, {toPrint, cast});
923
924
}
924
925
925
-
926
926
// / Generates code to handle finally block type semantics: always runs
927
927
// / regardless of whether a thrown exception is passing through or the
928
928
// / parent function is simply exiting. In addition to printing some state
@@ -996,10 +996,10 @@ static llvm::BasicBlock *createFinallyBlock(llvm::LLVMContext &context,
996
996
bufferToPrint.str (),
997
997
USE_GLOBAL_STR_CONSTS);
998
998
999
- llvm::SwitchInst *theSwitch = builder.CreateSwitch (builder. CreateLoad (
1000
- *exceptionCaughtFlag ),
1001
- &terminatorBlock ,
1002
- 2 );
999
+ llvm::SwitchInst *theSwitch = builder.CreateSwitch (
1000
+ builder. CreateLoad (ourExceptionNotThrownState-> getType ( ),
1001
+ *exceptionCaughtFlag) ,
1002
+ &terminatorBlock, 2 );
1003
1003
theSwitch->addCase (ourExceptionCaughtState, &terminatorBlock);
1004
1004
theSwitch->addCase (ourExceptionThrownState, &unwindResumeBlock);
1005
1005
@@ -1185,7 +1185,7 @@ static llvm::Function *createCatchWrappedInvokeFunction(
1185
1185
1186
1186
// Note: function handles NULL exceptions
1187
1187
builder.CreateCall (deleteOurException,
1188
- builder.CreateLoad (exceptionStorage));
1188
+ builder.CreateLoad (builder. getPtrTy (), exceptionStorage));
1189
1189
builder.CreateRetVoid ();
1190
1190
1191
1191
// Normal Block
@@ -1205,7 +1205,8 @@ static llvm::Function *createCatchWrappedInvokeFunction(
1205
1205
1206
1206
builder.SetInsertPoint (unwindResumeBlock);
1207
1207
1208
- builder.CreateResume (builder.CreateLoad (caughtResultStorage));
1208
+ builder.CreateResume (
1209
+ builder.CreateLoad (ourCaughtResultType, caughtResultStorage));
1209
1210
1210
1211
// Exception Block
1211
1212
@@ -1240,11 +1241,9 @@ static llvm::Function *createCatchWrappedInvokeFunction(
1240
1241
// Retrieve exception_class member from thrown exception
1241
1242
// (_Unwind_Exception instance). This member tells us whether or not
1242
1243
// the exception is foreign.
1243
- llvm::Value *unwindExceptionClass =
1244
- builder.CreateLoad (builder.CreateStructGEP (
1245
- ourUnwindExceptionType,
1246
- unwindException,
1247
- 0 ));
1244
+ llvm::Value *unwindExceptionClass = builder.CreateLoad (
1245
+ builder.getInt64Ty (),
1246
+ builder.CreateStructGEP (ourUnwindExceptionType, unwindException, 0 ));
1248
1247
1249
1248
// Branch to the externalExceptionBlock if the exception is foreign or
1250
1249
// to a catch router if not. Either way the finally block will be run.
@@ -1275,8 +1274,8 @@ static llvm::Function *createCatchWrappedInvokeFunction(
1275
1274
// (OurException instance).
1276
1275
//
1277
1276
// Note: ourBaseFromUnwindOffset is usually negative
1278
- llvm::Value *typeInfoThrown = builder.CreateConstGEP1_64 (unwindException,
1279
- ourBaseFromUnwindOffset) );
1277
+ llvm::Value *typeInfoThrown = builder.CreateConstGEP1_64 (
1278
+ builder. getInt8Ty (), unwindException, ourBaseFromUnwindOffset);
1280
1279
1281
1280
// Retrieve thrown exception type info type
1282
1281
//
@@ -1285,17 +1284,14 @@ static llvm::Function *createCatchWrappedInvokeFunction(
1285
1284
typeInfoThrown = builder.CreateStructGEP (ourExceptionType, typeInfoThrown, 0 );
1286
1285
1287
1286
llvm::Value *typeInfoThrownType =
1288
- builder.CreateStructGEP (builder. getPtrTy () , typeInfoThrown, 0 );
1287
+ builder.CreateStructGEP (ourTypeInfoType , typeInfoThrown, 0 );
1289
1288
1290
- generateIntegerPrint (context,
1291
- module ,
1292
- builder,
1293
- *toPrint32Int,
1294
- *(builder.CreateLoad (typeInfoThrownType)),
1289
+ llvm::Value *ti32 =
1290
+ builder.CreateLoad (builder.getInt32Ty (), typeInfoThrownType);
1291
+ generateIntegerPrint (context, module , builder, *toPrint32Int, ti32,
1295
1292
" Gen: Exception type <%d> received (stack unwound) "
1296
1293
" in " +
1297
- ourId +
1298
- " .\n " ,
1294
+ ourId + " .\n " ,
1299
1295
USE_GLOBAL_STR_CONSTS);
1300
1296
1301
1297
// Route to matched type info catch block or run cleanup finally block
@@ -1307,8 +1303,7 @@ static llvm::Function *createCatchWrappedInvokeFunction(
1307
1303
1308
1304
for (unsigned i = 1 ; i <= numExceptionsToCatch; ++i) {
1309
1305
nextTypeToCatch = i - 1 ;
1310
- switchToCatchBlock->addCase (llvm::ConstantInt::get (
1311
- llvm::Type::getInt32Ty (context), i),
1306
+ switchToCatchBlock->addCase (llvm::ConstantInt::get (builder.getInt32Ty (), i),
1312
1307
catchBlocks[nextTypeToCatch]);
1313
1308
}
1314
1309
@@ -1383,14 +1378,10 @@ createThrowExceptionFunction(llvm::Module &module, llvm::IRBuilder<> &builder,
1383
1378
builder.SetInsertPoint (entryBlock);
1384
1379
1385
1380
llvm::Function *toPrint32Int = module .getFunction (" print32Int" );
1386
- generateIntegerPrint (context,
1387
- module ,
1388
- builder,
1389
- *toPrint32Int,
1390
- *exceptionType,
1391
- " \n Gen: About to throw exception type <%d> in " +
1392
- ourId +
1393
- " .\n " ,
1381
+ generateIntegerPrint (context, module , builder, *toPrint32Int,
1382
+ builder.CreateZExt (exceptionType, builder.getInt32Ty ()),
1383
+ " \n Gen: About to throw exception type <%d> in " + ourId +
1384
+ " .\n " ,
1394
1385
USE_GLOBAL_STR_CONSTS);
1395
1386
1396
1387
// Switches on runtime type info type value to determine whether or not
@@ -1542,15 +1533,12 @@ typedef void (*OurExceptionThrowFunctType) (int32_t typeToThrow);
1542
1533
// / @param function generated test function to run
1543
1534
// / @param typeToThrow type info type of generated exception to throw, or
1544
1535
// / indicator to cause foreign exception to be thrown.
1545
- static
1546
- void runExceptionThrow (llvm::ExecutionEngine *engine,
1547
- llvm::Function *function,
1548
- int32_t typeToThrow) {
1536
+ static void runExceptionThrow (llvm::orc::LLJIT *JIT, std::string function,
1537
+ int32_t typeToThrow) {
1549
1538
1550
1539
// Find test's function pointer
1551
1540
OurExceptionThrowFunctType functPtr =
1552
- reinterpret_cast <OurExceptionThrowFunctType>(
1553
- reinterpret_cast <intptr_t >(engine->getPointerToFunction (function)));
1541
+ ExitOnErr (JIT->lookup (function)).toPtr <OurExceptionThrowFunctType>();
1554
1542
1555
1543
try {
1556
1544
// Run test
@@ -1579,8 +1567,6 @@ void runExceptionThrow(llvm::ExecutionEngine *engine,
1579
1567
// End test functions
1580
1568
//
1581
1569
1582
- typedef llvm::ArrayRef<llvm::Type*> TypeArray;
1583
-
1584
1570
// / This initialization routine creates type info globals and
1585
1571
// / adds external function declarations to module.
1586
1572
// / @param numTypeInfos number of linear type info associated type info types
@@ -1861,7 +1847,8 @@ static void createStandardUtilityFunctions(unsigned numTypeInfos,
1861
1847
1862
1848
// llvm.eh.typeid.for intrinsic
1863
1849
1864
- getDeclaration (&module , llvm::Intrinsic::eh_typeid_for, builder.getPtrTy ());
1850
+ getOrInsertDeclaration (&module , llvm::Intrinsic::eh_typeid_for,
1851
+ builder.getPtrTy ());
1865
1852
}
1866
1853
1867
1854
@@ -1890,93 +1877,73 @@ int main(int argc, char *argv[]) {
1890
1877
return (0 );
1891
1878
}
1892
1879
1893
- // If not set, exception handling will not be turned on
1894
- llvm::TargetOptions Opts;
1895
-
1896
1880
llvm::InitializeNativeTarget ();
1897
1881
llvm::InitializeNativeTargetAsmPrinter ();
1898
- llvm::LLVMContext Context ;
1899
- llvm::IRBuilder<> theBuilder (Context);
1882
+ auto Context = std::make_unique< llvm::LLVMContext>() ;
1883
+ llvm::IRBuilder<> theBuilder (* Context);
1900
1884
1901
1885
// Make the module, which holds all the code.
1902
1886
std::unique_ptr<llvm::Module> Owner =
1903
- std::make_unique<llvm::Module>(" my cool jit" , Context);
1887
+ std::make_unique<llvm::Module>(" my cool jit" , * Context);
1904
1888
llvm::Module *module = Owner.get ();
1905
1889
1906
- std::unique_ptr<llvm::RTDyldMemoryManager> MemMgr (new llvm::SectionMemoryManager ());
1890
+ // Build LLJIT
1891
+ std::unique_ptr<llvm::orc::LLJIT> JIT =
1892
+ ExitOnErr (llvm::orc::LLJITBuilder ().create ());
1907
1893
1908
- // Build engine with JIT
1909
- llvm::EngineBuilder factory (std::move (Owner));
1910
- factory.setEngineKind (llvm::EngineKind::JIT);
1911
- factory.setTargetOptions (Opts);
1912
- factory.setMCJITMemoryManager (std::move (MemMgr));
1913
- llvm::ExecutionEngine *executionEngine = factory.create ();
1894
+ // Set up the optimizer pipeline.
1895
+ llvm::legacy::FunctionPassManager fpm (module );
1914
1896
1915
- {
1916
- llvm::legacy::FunctionPassManager fpm (module );
1917
-
1918
- // Set up the optimizer pipeline.
1919
- // Start with registering info about how the
1920
- // target lays out data structures.
1921
- module ->setDataLayout (executionEngine->getDataLayout ());
1922
-
1923
- // Optimizations turned on
1897
+ // Optimizations turned on
1924
1898
#ifdef ADD_OPT_PASSES
1925
1899
1926
- // Basic AliasAnslysis support for GVN.
1927
- fpm.add (llvm::createBasicAliasAnalysisPass ());
1900
+ // Basic AliasAnslysis support for GVN.
1901
+ fpm.add (llvm::createBasicAliasAnalysisPass ());
1928
1902
1929
- // Promote allocas to registers.
1930
- fpm.add (llvm::createPromoteMemoryToRegisterPass ());
1903
+ // Promote allocas to registers.
1904
+ fpm.add (llvm::createPromoteMemoryToRegisterPass ());
1931
1905
1932
- // Do simple "peephole" optimizations and bit-twiddling optzns.
1933
- fpm.add (llvm::createInstructionCombiningPass ());
1906
+ // Do simple "peephole" optimizations and bit-twiddling optzns.
1907
+ fpm.add (llvm::createInstructionCombiningPass ());
1934
1908
1935
- // Reassociate expressions.
1936
- fpm.add (llvm::createReassociatePass ());
1909
+ // Reassociate expressions.
1910
+ fpm.add (llvm::createReassociatePass ());
1937
1911
1938
- // Eliminate Common SubExpressions.
1939
- fpm.add (llvm::createGVNPass ());
1912
+ // Eliminate Common SubExpressions.
1913
+ fpm.add (llvm::createGVNPass ());
1940
1914
1941
- // Simplify the control flow graph (deleting unreachable
1942
- // blocks, etc).
1943
- fpm.add (llvm::createCFGSimplificationPass ());
1915
+ // Simplify the control flow graph (deleting unreachable
1916
+ // blocks, etc).
1917
+ fpm.add (llvm::createCFGSimplificationPass ());
1944
1918
#endif // ADD_OPT_PASSES
1945
1919
1946
- fpm.doInitialization ();
1920
+ fpm.doInitialization ();
1947
1921
1948
- // Generate test code using function throwCppException(...) as
1949
- // the function which throws foreign exceptions.
1950
- llvm::Function *toRun =
1951
- createUnwindExceptionTest (*module ,
1952
- theBuilder,
1953
- fpm,
1954
- " throwCppException" );
1922
+ // Generate test code using function throwCppException(...) as
1923
+ // the function which throws foreign exceptions.
1924
+ createUnwindExceptionTest (*module , theBuilder, fpm, " throwCppException" );
1955
1925
1956
- executionEngine->finalizeObject ();
1926
+ ExitOnErr (JIT->addIRModule (
1927
+ llvm::orc::ThreadSafeModule (std::move (Owner), std::move (Context))));
1957
1928
1958
1929
#ifndef NDEBUG
1959
- fprintf (stderr, " \n Begin module dump:\n\n " );
1930
+ fprintf (stderr, " \n Begin module dump:\n\n " );
1960
1931
1961
- module ->dump ( );
1932
+ module ->print ( llvm::errs (), nullptr );
1962
1933
1963
- fprintf (stderr, " \n End module dump:\n " );
1934
+ fprintf (stderr, " \n End module dump:\n " );
1964
1935
#endif
1965
1936
1966
- fprintf (stderr, " \n\n Begin Test:\n " );
1967
-
1968
- for (int i = 1 ; i < argc; ++i) {
1969
- // Run test for each argument whose value is the exception
1970
- // type to throw.
1971
- runExceptionThrow (executionEngine,
1972
- toRun,
1973
- (unsigned ) strtoul (argv[i], NULL , 10 ));
1974
- }
1937
+ fprintf (stderr, " \n\n Begin Test:\n " );
1938
+ std::string toRun = " outerCatchFunct" ;
1975
1939
1976
- fprintf (stderr, " \n End Test:\n\n " );
1940
+ for (int i = 1 ; i < argc; ++i) {
1941
+ // Run test for each argument whose value is the exception
1942
+ // type to throw.
1943
+ runExceptionThrow (JIT.get (), toRun, (unsigned )strtoul (argv[i], NULL , 10 ));
1977
1944
}
1978
1945
1979
- delete executionEngine ;
1946
+ fprintf (stderr, " \n End Test: \n\n " ) ;
1980
1947
1981
1948
return 0 ;
1982
1949
}
0 commit comments