4949
5050#include " llvm/ADT/STLExtras.h"
5151#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"
5455#include " llvm/IR/DataLayout.h"
5556#include " llvm/IR/DerivedTypes.h"
5657#include " llvm/IR/IRBuilder.h"
8485#define USE_GLOBAL_STR_CONSTS true
8586#endif
8687
88+ llvm::ExitOnError ExitOnErr;
89+
8790//
8891// Example types
8992//
@@ -142,6 +145,7 @@ static llvm::ConstantInt *ourExceptionCaughtState;
142145
143146typedef std::vector<std::string> ArgNames;
144147typedef std::vector<llvm::Type*> ArgTypes;
148+ typedef llvm::ArrayRef<llvm::Type *> TypeArray;
145149
146150//
147151// Code Generation Utilities
@@ -891,13 +895,10 @@ void generateStringPrint(llvm::LLVMContext &context,
891895// / generated, and is used to hold the constant string. A value of
892896// / false indicates that the constant string will be stored on the
893897// / stack.
894- void generateIntegerPrint (llvm::LLVMContext &context,
895- llvm::Module &module ,
898+ void generateIntegerPrint (llvm::LLVMContext &context, llvm::Module &module ,
896899 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 ) {
901902 llvm::Constant *stringConstant =
902903 llvm::ConstantDataArray::getString (context, format);
903904 llvm::Value *stringVar;
@@ -919,10 +920,9 @@ void generateIntegerPrint(llvm::LLVMContext &context,
919920
920921 llvm::Value *cast = builder.CreateBitCast (stringVar,
921922 builder.getPtrTy ());
922- builder.CreateCall (&printFunct, {& toPrint, cast});
923+ builder.CreateCall (&printFunct, {toPrint, cast});
923924}
924925
925-
926926// / Generates code to handle finally block type semantics: always runs
927927// / regardless of whether a thrown exception is passing through or the
928928// / parent function is simply exiting. In addition to printing some state
@@ -996,10 +996,10 @@ static llvm::BasicBlock *createFinallyBlock(llvm::LLVMContext &context,
996996 bufferToPrint.str (),
997997 USE_GLOBAL_STR_CONSTS);
998998
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 );
10031003 theSwitch->addCase (ourExceptionCaughtState, &terminatorBlock);
10041004 theSwitch->addCase (ourExceptionThrownState, &unwindResumeBlock);
10051005
@@ -1185,7 +1185,7 @@ static llvm::Function *createCatchWrappedInvokeFunction(
11851185
11861186 // Note: function handles NULL exceptions
11871187 builder.CreateCall (deleteOurException,
1188- builder.CreateLoad (exceptionStorage));
1188+ builder.CreateLoad (builder. getPtrTy (), exceptionStorage));
11891189 builder.CreateRetVoid ();
11901190
11911191 // Normal Block
@@ -1205,7 +1205,8 @@ static llvm::Function *createCatchWrappedInvokeFunction(
12051205
12061206 builder.SetInsertPoint (unwindResumeBlock);
12071207
1208- builder.CreateResume (builder.CreateLoad (caughtResultStorage));
1208+ builder.CreateResume (
1209+ builder.CreateLoad (ourCaughtResultType, caughtResultStorage));
12091210
12101211 // Exception Block
12111212
@@ -1240,11 +1241,9 @@ static llvm::Function *createCatchWrappedInvokeFunction(
12401241 // Retrieve exception_class member from thrown exception
12411242 // (_Unwind_Exception instance). This member tells us whether or not
12421243 // 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 ));
12481247
12491248 // Branch to the externalExceptionBlock if the exception is foreign or
12501249 // to a catch router if not. Either way the finally block will be run.
@@ -1275,8 +1274,8 @@ static llvm::Function *createCatchWrappedInvokeFunction(
12751274 // (OurException instance).
12761275 //
12771276 // 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);
12801279
12811280 // Retrieve thrown exception type info type
12821281 //
@@ -1285,17 +1284,14 @@ static llvm::Function *createCatchWrappedInvokeFunction(
12851284 typeInfoThrown = builder.CreateStructGEP (ourExceptionType, typeInfoThrown, 0 );
12861285
12871286 llvm::Value *typeInfoThrownType =
1288- builder.CreateStructGEP (builder. getPtrTy () , typeInfoThrown, 0 );
1287+ builder.CreateStructGEP (ourTypeInfoType , typeInfoThrown, 0 );
12891288
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,
12951292 " Gen: Exception type <%d> received (stack unwound) "
12961293 " in " +
1297- ourId +
1298- " .\n " ,
1294+ ourId + " .\n " ,
12991295 USE_GLOBAL_STR_CONSTS);
13001296
13011297 // Route to matched type info catch block or run cleanup finally block
@@ -1307,8 +1303,7 @@ static llvm::Function *createCatchWrappedInvokeFunction(
13071303
13081304 for (unsigned i = 1 ; i <= numExceptionsToCatch; ++i) {
13091305 nextTypeToCatch = i - 1 ;
1310- switchToCatchBlock->addCase (llvm::ConstantInt::get (
1311- llvm::Type::getInt32Ty (context), i),
1306+ switchToCatchBlock->addCase (llvm::ConstantInt::get (builder.getInt32Ty (), i),
13121307 catchBlocks[nextTypeToCatch]);
13131308 }
13141309
@@ -1383,14 +1378,10 @@ createThrowExceptionFunction(llvm::Module &module, llvm::IRBuilder<> &builder,
13831378 builder.SetInsertPoint (entryBlock);
13841379
13851380 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 " ,
13941385 USE_GLOBAL_STR_CONSTS);
13951386
13961387 // Switches on runtime type info type value to determine whether or not
@@ -1542,15 +1533,12 @@ typedef void (*OurExceptionThrowFunctType) (int32_t typeToThrow);
15421533// / @param function generated test function to run
15431534// / @param typeToThrow type info type of generated exception to throw, or
15441535// / 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) {
15491538
15501539 // Find test's function pointer
15511540 OurExceptionThrowFunctType functPtr =
1552- reinterpret_cast <OurExceptionThrowFunctType>(
1553- reinterpret_cast <intptr_t >(engine->getPointerToFunction (function)));
1541+ ExitOnErr (JIT->lookup (function)).toPtr <OurExceptionThrowFunctType>();
15541542
15551543 try {
15561544 // Run test
@@ -1579,8 +1567,6 @@ void runExceptionThrow(llvm::ExecutionEngine *engine,
15791567// End test functions
15801568//
15811569
1582- typedef llvm::ArrayRef<llvm::Type*> TypeArray;
1583-
15841570// / This initialization routine creates type info globals and
15851571// / adds external function declarations to module.
15861572// / @param numTypeInfos number of linear type info associated type info types
@@ -1861,7 +1847,8 @@ static void createStandardUtilityFunctions(unsigned numTypeInfos,
18611847
18621848 // llvm.eh.typeid.for intrinsic
18631849
1864- getDeclaration (&module , llvm::Intrinsic::eh_typeid_for, builder.getPtrTy ());
1850+ getOrInsertDeclaration (&module , llvm::Intrinsic::eh_typeid_for,
1851+ builder.getPtrTy ());
18651852}
18661853
18671854
@@ -1890,93 +1877,73 @@ int main(int argc, char *argv[]) {
18901877 return (0 );
18911878 }
18921879
1893- // If not set, exception handling will not be turned on
1894- llvm::TargetOptions Opts;
1895-
18961880 llvm::InitializeNativeTarget ();
18971881 llvm::InitializeNativeTargetAsmPrinter ();
1898- llvm::LLVMContext Context ;
1899- llvm::IRBuilder<> theBuilder (Context);
1882+ auto Context = std::make_unique< llvm::LLVMContext>() ;
1883+ llvm::IRBuilder<> theBuilder (* Context);
19001884
19011885 // Make the module, which holds all the code.
19021886 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);
19041888 llvm::Module *module = Owner.get ();
19051889
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 ());
19071893
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 );
19141896
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
19241898#ifdef ADD_OPT_PASSES
19251899
1926- // Basic AliasAnslysis support for GVN.
1927- fpm.add (llvm::createBasicAliasAnalysisPass ());
1900+ // Basic AliasAnslysis support for GVN.
1901+ fpm.add (llvm::createBasicAliasAnalysisPass ());
19281902
1929- // Promote allocas to registers.
1930- fpm.add (llvm::createPromoteMemoryToRegisterPass ());
1903+ // Promote allocas to registers.
1904+ fpm.add (llvm::createPromoteMemoryToRegisterPass ());
19311905
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 ());
19341908
1935- // Reassociate expressions.
1936- fpm.add (llvm::createReassociatePass ());
1909+ // Reassociate expressions.
1910+ fpm.add (llvm::createReassociatePass ());
19371911
1938- // Eliminate Common SubExpressions.
1939- fpm.add (llvm::createGVNPass ());
1912+ // Eliminate Common SubExpressions.
1913+ fpm.add (llvm::createGVNPass ());
19401914
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 ());
19441918#endif // ADD_OPT_PASSES
19451919
1946- fpm.doInitialization ();
1920+ fpm.doInitialization ();
19471921
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" );
19551925
1956- executionEngine->finalizeObject ();
1926+ ExitOnErr (JIT->addIRModule (
1927+ llvm::orc::ThreadSafeModule (std::move (Owner), std::move (Context))));
19571928
19581929#ifndef NDEBUG
1959- fprintf (stderr, " \n Begin module dump:\n\n " );
1930+ fprintf (stderr, " \n Begin module dump:\n\n " );
19601931
1961- module ->dump ( );
1932+ module ->print ( llvm::errs (), nullptr );
19621933
1963- fprintf (stderr, " \n End module dump:\n " );
1934+ fprintf (stderr, " \n End module dump:\n " );
19641935#endif
19651936
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" ;
19751939
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 ));
19771944 }
19781945
1979- delete executionEngine ;
1946+ fprintf (stderr, " \n End Test: \n\n " ) ;
19801947
19811948 return 0 ;
19821949}
0 commit comments