Skip to content

Revert "[ExceptionDemo] Correct and update example ExceptionDemo" #92257

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion llvm/examples/ExceptionDemo/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
set(LLVM_LINK_COMPONENTS
Core
ExecutionEngine
ORCJIT
MC
MCJIT
RuntimeDyld
Support
Target
nativecodegen
Expand Down
181 changes: 105 additions & 76 deletions llvm/examples/ExceptionDemo/ExceptionDemo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,8 @@

#include "llvm/ADT/STLExtras.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/ExecutionEngine/Orc/Core.h"
#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
#include "llvm/ExecutionEngine/Orc/LLJIT.h"
#include "llvm/ExecutionEngine/MCJIT.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/IRBuilder.h"
Expand Down Expand Up @@ -85,8 +84,6 @@
#define USE_GLOBAL_STR_CONSTS true
#endif

llvm::ExitOnError ExitOnErr;

//
// Example types
//
Expand Down Expand Up @@ -145,7 +142,6 @@ static llvm::ConstantInt *ourExceptionCaughtState;

typedef std::vector<std::string> ArgNames;
typedef std::vector<llvm::Type*> ArgTypes;
typedef llvm::ArrayRef<llvm::Type *> TypeArray;

//
// Code Generation Utilities
Expand Down Expand Up @@ -896,10 +892,13 @@ void generateStringPrint(llvm::LLVMContext &context,
/// generated, and is used to hold the constant string. A value of
/// false indicates that the constant string will be stored on the
/// stack.
void generateIntegerPrint(llvm::LLVMContext &context, llvm::Module &module,
void generateIntegerPrint(llvm::LLVMContext &context,
llvm::Module &module,
llvm::IRBuilder<> &builder,
llvm::Function &printFunct, llvm::Value *toPrint,
std::string format, bool useGlobal = true) {
llvm::Function &printFunct,
llvm::Value &toPrint,
std::string format,
bool useGlobal = true) {
llvm::Constant *stringConstant =
llvm::ConstantDataArray::getString(context, format);
llvm::Value *stringVar;
Expand All @@ -921,9 +920,10 @@ void generateIntegerPrint(llvm::LLVMContext &context, llvm::Module &module,

llvm::Value *cast = builder.CreateBitCast(stringVar,
builder.getPtrTy());
builder.CreateCall(&printFunct, {toPrint, cast});
builder.CreateCall(&printFunct, {&toPrint, cast});
}


/// Generates code to handle finally block type semantics: always runs
/// regardless of whether a thrown exception is passing through or the
/// parent function is simply exiting. In addition to printing some state
Expand Down Expand Up @@ -997,10 +997,10 @@ static llvm::BasicBlock *createFinallyBlock(llvm::LLVMContext &context,
bufferToPrint.str(),
USE_GLOBAL_STR_CONSTS);

llvm::SwitchInst *theSwitch = builder.CreateSwitch(
builder.CreateLoad(ourExceptionNotThrownState->getType(),
*exceptionCaughtFlag),
&terminatorBlock, 2);
llvm::SwitchInst *theSwitch = builder.CreateSwitch(builder.CreateLoad(
*exceptionCaughtFlag),
&terminatorBlock,
2);
theSwitch->addCase(ourExceptionCaughtState, &terminatorBlock);
theSwitch->addCase(ourExceptionThrownState, &unwindResumeBlock);

Expand Down Expand Up @@ -1186,7 +1186,7 @@ static llvm::Function *createCatchWrappedInvokeFunction(

// Note: function handles NULL exceptions
builder.CreateCall(deleteOurException,
builder.CreateLoad(builder.getPtrTy(), exceptionStorage));
builder.CreateLoad(exceptionStorage));
builder.CreateRetVoid();

// Normal Block
Expand All @@ -1206,8 +1206,7 @@ static llvm::Function *createCatchWrappedInvokeFunction(

builder.SetInsertPoint(unwindResumeBlock);

builder.CreateResume(
builder.CreateLoad(ourCaughtResultType, caughtResultStorage));
builder.CreateResume(builder.CreateLoad(caughtResultStorage));

// Exception Block

Expand Down Expand Up @@ -1242,9 +1241,8 @@ static llvm::Function *createCatchWrappedInvokeFunction(
// Retrieve exception_class member from thrown exception
// (_Unwind_Exception instance). This member tells us whether or not
// the exception is foreign.
llvm::Value *unwindExceptionClass = builder.CreateLoad(
builder.getInt64Ty(),
builder.CreateStructGEP(
llvm::Value *unwindExceptionClass =
builder.CreateLoad(builder.CreateStructGEP(
ourUnwindExceptionType,
builder.CreatePointerCast(unwindException,
ourUnwindExceptionType->getPointerTo()),
Expand Down Expand Up @@ -1280,9 +1278,9 @@ static llvm::Function *createCatchWrappedInvokeFunction(
//
// Note: ourBaseFromUnwindOffset is usually negative
llvm::Value *typeInfoThrown = builder.CreatePointerCast(
builder.CreateConstGEP1_64(builder.getPtrTy(), unwindException,
ourBaseFromUnwindOffset),
ourExceptionType->getPointerTo());
builder.CreateConstGEP1_64(unwindException,
ourBaseFromUnwindOffset),
ourExceptionType->getPointerTo());

// Retrieve thrown exception type info type
//
Expand All @@ -1291,15 +1289,17 @@ static llvm::Function *createCatchWrappedInvokeFunction(
typeInfoThrown = builder.CreateStructGEP(ourExceptionType, typeInfoThrown, 0);

llvm::Value *typeInfoThrownType =
builder.CreateStructGEP(ourTypeInfoType, typeInfoThrown, 0);
builder.CreateStructGEP(builder.getPtrTy(), typeInfoThrown, 0);

llvm::Value *ti8 =
builder.CreateLoad(builder.getInt8Ty(), typeInfoThrownType);
generateIntegerPrint(context, module, builder, *toPrint32Int,
builder.CreateZExt(ti8, builder.getInt32Ty()),
generateIntegerPrint(context,
module,
builder,
*toPrint32Int,
*(builder.CreateLoad(typeInfoThrownType)),
"Gen: Exception type <%d> received (stack unwound) "
" in " +
ourId + ".\n",
ourId +
".\n",
USE_GLOBAL_STR_CONSTS);

// Route to matched type info catch block or run cleanup finally block
Expand All @@ -1311,7 +1311,8 @@ static llvm::Function *createCatchWrappedInvokeFunction(

for (unsigned i = 1; i <= numExceptionsToCatch; ++i) {
nextTypeToCatch = i - 1;
switchToCatchBlock->addCase(llvm::ConstantInt::get(builder.getInt32Ty(), i),
switchToCatchBlock->addCase(llvm::ConstantInt::get(
llvm::Type::getInt32Ty(context), i),
catchBlocks[nextTypeToCatch]);
}

Expand Down Expand Up @@ -1386,10 +1387,14 @@ createThrowExceptionFunction(llvm::Module &module, llvm::IRBuilder<> &builder,
builder.SetInsertPoint(entryBlock);

llvm::Function *toPrint32Int = module.getFunction("print32Int");
generateIntegerPrint(context, module, builder, *toPrint32Int,
builder.CreateZExt(exceptionType, builder.getInt32Ty()),
"\nGen: About to throw exception type <%d> in " + ourId +
".\n",
generateIntegerPrint(context,
module,
builder,
*toPrint32Int,
*exceptionType,
"\nGen: About to throw exception type <%d> in " +
ourId +
".\n",
USE_GLOBAL_STR_CONSTS);

// Switches on runtime type info type value to determine whether or not
Expand Down Expand Up @@ -1541,13 +1546,15 @@ typedef void (*OurExceptionThrowFunctType) (int32_t typeToThrow);
/// @param function generated test function to run
/// @param typeToThrow type info type of generated exception to throw, or
/// indicator to cause foreign exception to be thrown.
static void runExceptionThrow(llvm::orc::LLJIT *JIT, std::string function,
int32_t typeToThrow) {
static
void runExceptionThrow(llvm::ExecutionEngine *engine,
llvm::Function *function,
int32_t typeToThrow) {

// Find test's function pointer
OurExceptionThrowFunctType functPtr =
reinterpret_cast<OurExceptionThrowFunctType>(reinterpret_cast<uintptr_t>(
ExitOnErr(JIT->lookup(function)).getValue()));
reinterpret_cast<OurExceptionThrowFunctType>(
reinterpret_cast<intptr_t>(engine->getPointerToFunction(function)));

try {
// Run test
Expand Down Expand Up @@ -1576,6 +1583,8 @@ static void runExceptionThrow(llvm::orc::LLJIT *JIT, std::string function,
// End test functions
//

typedef llvm::ArrayRef<llvm::Type*> TypeArray;

/// This initialization routine creates type info globals and
/// adds external function declarations to module.
/// @param numTypeInfos number of linear type info associated type info types
Expand Down Expand Up @@ -1885,73 +1894,93 @@ int main(int argc, char *argv[]) {
return(0);
}

// If not set, exception handling will not be turned on
llvm::TargetOptions Opts;

llvm::InitializeNativeTarget();
llvm::InitializeNativeTargetAsmPrinter();
auto Context = std::make_unique<llvm::LLVMContext>();
llvm::IRBuilder<> theBuilder(*Context);
llvm::LLVMContext Context;
llvm::IRBuilder<> theBuilder(Context);

// Make the module, which holds all the code.
std::unique_ptr<llvm::Module> Owner =
std::make_unique<llvm::Module>("my cool jit", *Context);
std::make_unique<llvm::Module>("my cool jit", Context);
llvm::Module *module = Owner.get();

// Build LLJIT
std::unique_ptr<llvm::orc::LLJIT> JIT =
ExitOnErr(llvm::orc::LLJITBuilder().create());
std::unique_ptr<llvm::RTDyldMemoryManager> MemMgr(new llvm::SectionMemoryManager());

// Set up the optimizer pipeline.
llvm::legacy::FunctionPassManager fpm(module);
// Build engine with JIT
llvm::EngineBuilder factory(std::move(Owner));
factory.setEngineKind(llvm::EngineKind::JIT);
factory.setTargetOptions(Opts);
factory.setMCJITMemoryManager(std::move(MemMgr));
llvm::ExecutionEngine *executionEngine = factory.create();

// Optimizations turned on
{
llvm::legacy::FunctionPassManager fpm(module);

// Set up the optimizer pipeline.
// Start with registering info about how the
// target lays out data structures.
module->setDataLayout(executionEngine->getDataLayout());

// Optimizations turned on
#ifdef ADD_OPT_PASSES

// Basic AliasAnslysis support for GVN.
fpm.add(llvm::createBasicAliasAnalysisPass());
// Basic AliasAnslysis support for GVN.
fpm.add(llvm::createBasicAliasAnalysisPass());

// Promote allocas to registers.
fpm.add(llvm::createPromoteMemoryToRegisterPass());
// Promote allocas to registers.
fpm.add(llvm::createPromoteMemoryToRegisterPass());

// Do simple "peephole" optimizations and bit-twiddling optzns.
fpm.add(llvm::createInstructionCombiningPass());
// Do simple "peephole" optimizations and bit-twiddling optzns.
fpm.add(llvm::createInstructionCombiningPass());

// Reassociate expressions.
fpm.add(llvm::createReassociatePass());
// Reassociate expressions.
fpm.add(llvm::createReassociatePass());

// Eliminate Common SubExpressions.
fpm.add(llvm::createGVNPass());
// Eliminate Common SubExpressions.
fpm.add(llvm::createGVNPass());

// Simplify the control flow graph (deleting unreachable
// blocks, etc).
fpm.add(llvm::createCFGSimplificationPass());
// Simplify the control flow graph (deleting unreachable
// blocks, etc).
fpm.add(llvm::createCFGSimplificationPass());
#endif // ADD_OPT_PASSES

fpm.doInitialization();
fpm.doInitialization();

// Generate test code using function throwCppException(...) as
// the function which throws foreign exceptions.
createUnwindExceptionTest(*module, theBuilder, fpm, "throwCppException");
// Generate test code using function throwCppException(...) as
// the function which throws foreign exceptions.
llvm::Function *toRun =
createUnwindExceptionTest(*module,
theBuilder,
fpm,
"throwCppException");

ExitOnErr(JIT->addIRModule(
llvm::orc::ThreadSafeModule(std::move(Owner), std::move(Context))));
executionEngine->finalizeObject();

#ifndef NDEBUG
fprintf(stderr, "\nBegin module dump:\n\n");
fprintf(stderr, "\nBegin module dump:\n\n");

module->print(llvm::errs(), nullptr);
module->dump();

fprintf(stderr, "\nEnd module dump:\n");
fprintf(stderr, "\nEnd module dump:\n");
#endif

fprintf(stderr, "\n\nBegin Test:\n");
std::string toRun = "outerCatchFunct";
fprintf(stderr, "\n\nBegin Test:\n");

for (int i = 1; i < argc; ++i) {
// Run test for each argument whose value is the exception
// type to throw.
runExceptionThrow(executionEngine,
toRun,
(unsigned) strtoul(argv[i], NULL, 10));
}

for (int i = 1; i < argc; ++i) {
// Run test for each argument whose value is the exception
// type to throw.
runExceptionThrow(JIT.get(), toRun, (unsigned)strtoul(argv[i], NULL, 10));
fprintf(stderr, "\nEnd Test:\n\n");
}

fprintf(stderr, "\nEnd Test:\n\n");
delete executionEngine;

return 0;
}
Loading