diff options
author | Owen Anderson <resistor@mac.com> | 2010-08-30 21:34:26 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2010-08-30 21:34:26 +0000 |
commit | 060bb6bb4a956380db4052c4fb163081f1a7424a (patch) | |
tree | f4142fffd6702d7e4072bc67c759e78a22477246 /examples/TracingBrainF/BrainFCodeGen.cpp | |
parent | 56b092e4cd2679d5d2dc892c722fa912e0dccbf9 (diff) |
Remove this from the main tree. I'll host it out of tree.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@112529 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'examples/TracingBrainF/BrainFCodeGen.cpp')
-rw-r--r-- | examples/TracingBrainF/BrainFCodeGen.cpp | 351 |
1 files changed, 0 insertions, 351 deletions
diff --git a/examples/TracingBrainF/BrainFCodeGen.cpp b/examples/TracingBrainF/BrainFCodeGen.cpp deleted file mode 100644 index 87965460ce..0000000000 --- a/examples/TracingBrainF/BrainFCodeGen.cpp +++ /dev/null @@ -1,351 +0,0 @@ -//===-- BrainFCodeGen.cpp - BrainF trace compiler -----------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===--------------------------------------------------------------------===// - -#include "BrainF.h" -#include "BrainFVM.h" -#include "llvm/Attributes.h" -#include "llvm/Support/StandardPasses.h" -#include "llvm/Target/TargetData.h" -#include "llvm/Target/TargetSelect.h" -#include "llvm/Transforms/Scalar.h" -#include "llvm/ADT/StringExtras.h" - -/// initialize_module - perform setup of the LLVM code generation system. -void BrainFTraceRecorder::initialize_module() { - LLVMContext &Context = module->getContext(); - - // Initialize the code generator, and enable aggressive code generation. - InitializeNativeTarget(); - EngineBuilder builder(module); - builder.setOptLevel(CodeGenOpt::Aggressive); - EE = builder.create(); - - // Create a FunctionPassManager to handle running optimization passes - // on our generated code. Setup a basic suite of optimizations for it. - FPM = new llvm::FunctionPassManager(module); - FPM->add(createInstructionCombiningPass()); - FPM->add(createCFGSimplificationPass()); - FPM->add(createScalarReplAggregatesPass()); - FPM->add(createSimplifyLibCallsPass()); - FPM->add(createInstructionCombiningPass()); - FPM->add(createJumpThreadingPass()); - FPM->add(createCFGSimplificationPass()); - FPM->add(createInstructionCombiningPass()); - FPM->add(createCFGSimplificationPass()); - FPM->add(createReassociatePass()); - FPM->add(createLoopRotatePass()); - FPM->add(createLICMPass()); - FPM->add(createLoopUnswitchPass(false)); - FPM->add(createInstructionCombiningPass()); - FPM->add(createIndVarSimplifyPass()); - FPM->add(createLoopDeletionPass()); - FPM->add(createLoopUnrollPass()); - FPM->add(createInstructionCombiningPass()); - FPM->add(createGVNPass()); - FPM->add(createSCCPPass()); - FPM->add(createInstructionCombiningPass()); - FPM->add(createJumpThreadingPass()); - FPM->add(createDeadStoreEliminationPass()); - FPM->add(createAggressiveDCEPass()); - FPM->add(createCFGSimplificationPass()); - - // Cache the LLVM type signature of an opcode function - int_type = sizeof(size_t) == 4 ? - IntegerType::getInt32Ty(Context) : - IntegerType::getInt64Ty(Context); - const Type *data_type = - PointerType::getUnqual(IntegerType::getInt8Ty(Context)); - std::vector<const Type*> args; - args.push_back(int_type); - args.push_back(data_type); - op_type = - FunctionType::get(Type::getVoidTy(Context), args, false); - - // Setup a global variable in the LLVM module to represent the bytecode - // array. Bind it to the actual bytecode array at JIT time. - const Type *bytecode_type = PointerType::getUnqual(op_type); - bytecode_array = cast<GlobalValue>(module-> - getOrInsertGlobal("BytecodeArray", bytecode_type)); - EE->addGlobalMapping(bytecode_array, BytecodeArray); - - // Setup a similar mapping for the global executed flag. - const IntegerType *flag_type = IntegerType::get(Context, 8); - executed_flag = - cast<GlobalValue>(module->getOrInsertGlobal("executed", flag_type)); - EE->addGlobalMapping(executed_flag, &executed); - - // Cache LLVM declarations for putchar() and getchar(). - const Type *int_type = sizeof(int) == 4 ? IntegerType::getInt32Ty(Context) - : IntegerType::getInt64Ty(Context); - putchar_func = - module->getOrInsertFunction("putchar", int_type, int_type, NULL); - getchar_func = module->getOrInsertFunction("getchar", int_type, NULL); -} - -void BrainFTraceRecorder::compile(BrainFTraceNode* trace) { - LLVMContext &Context = module->getContext(); - - // Create a new function for the trace we're compiling. - Function *curr_func = cast<Function>(module-> - getOrInsertFunction("trace_"+utostr(trace->pc), op_type)); - - // Create an entry block, which branches directly to a header block. - // This is necessary because the entry block cannot be the target of - // a loop. - BasicBlock *Entry = BasicBlock::Create(Context, "entry", curr_func); - Header = BasicBlock::Create(Context, utostr(trace->pc), curr_func); - - // Mark the array pointer as noalias, and setup compiler state. - IRBuilder<> builder(Entry); - Argument *Arg1 = ++curr_func->arg_begin(); - Arg1->addAttr(Attribute::NoAlias); - DataPtr = Arg1; - - // Emit code to set the executed flag. This signals to the recorder - // that the preceding opcode was executed as a part of a compiled trace. - const IntegerType *flag_type = IntegerType::get(Context, 8); - ConstantInt *True = ConstantInt::get(flag_type, 1); - builder.CreateStore(True, executed_flag); - builder.CreateBr(Header); - - // Header will be the root of our trace tree. As such, all loop back-edges - // will be targetting it. Setup a PHI node to merge together incoming values - // for the current array pointer as we loop. - builder.SetInsertPoint(Header); - HeaderPHI = builder.CreatePHI(DataPtr->getType()); - HeaderPHI->addIncoming(DataPtr, Entry); - DataPtr = HeaderPHI; - - // Recursively descend the trace tree, emitting code for the opcodes as we go. - compile_opcode(trace, builder); - - // Run out optimization suite on our newly generated trace. - FPM->run(*curr_func); - - // Compile our trace to machine code, and install function pointer to it - // into the bytecode array so that it will be executed every time the - // trace-head PC is reached. - void *code = EE->getPointerToFunction(curr_func); - BytecodeArray[trace->pc] = - (opcode_func_t)(intptr_t)code; -} - -/// compile_plus - Emit code for '+' -void BrainFTraceRecorder::compile_plus(BrainFTraceNode *node, - IRBuilder<>& builder) { - Value *CellValue = builder.CreateLoad(DataPtr); - Constant *One = - ConstantInt::get(IntegerType::getInt8Ty(Header->getContext()), 1); - Value *UpdatedValue = builder.CreateAdd(CellValue, One); - builder.CreateStore(UpdatedValue, DataPtr); - - if (node->left != (BrainFTraceNode*)~0ULL) - compile_opcode(node->left, builder); - else { - HeaderPHI->addIncoming(DataPtr, builder.GetInsertBlock()); - builder.CreateBr(Header); - } -} - -/// compile_minus - Emit code for '-' -void BrainFTraceRecorder::compile_minus(BrainFTraceNode *node, - IRBuilder<>& builder) { - Value *CellValue = builder.CreateLoad(DataPtr); - Constant *One = - ConstantInt::get(IntegerType::getInt8Ty(Header->getContext()), 1); - Value *UpdatedValue = builder.CreateSub(CellValue, One); - builder.CreateStore(UpdatedValue, DataPtr); - - if (node->left != (BrainFTraceNode*)~0ULL) - compile_opcode(node->left, builder); - else { - HeaderPHI->addIncoming(DataPtr, builder.GetInsertBlock()); - builder.CreateBr(Header); - } -} - -/// compile_left - Emit code for '<' -void BrainFTraceRecorder::compile_left(BrainFTraceNode *node, - IRBuilder<>& builder) { - Value *OldPtr = DataPtr; - DataPtr = builder.CreateConstInBoundsGEP1_32(DataPtr, -1); - if (node->left != (BrainFTraceNode*)~0ULL) - compile_opcode(node->left, builder); - else { - HeaderPHI->addIncoming(DataPtr, builder.GetInsertBlock()); - builder.CreateBr(Header); - } - DataPtr = OldPtr; -} - -/// compile_right - Emit code for '>' -void BrainFTraceRecorder::compile_right(BrainFTraceNode *node, - IRBuilder<>& builder) { - Value *OldPtr = DataPtr; - DataPtr = builder.CreateConstInBoundsGEP1_32(DataPtr, 1); - if (node->left != (BrainFTraceNode*)~0ULL) - compile_opcode(node->left, builder); - else { - HeaderPHI->addIncoming(DataPtr, builder.GetInsertBlock()); - builder.CreateBr(Header); - } - DataPtr = OldPtr; -} - - -/// compile_put - Emit code for '.' -void BrainFTraceRecorder::compile_put(BrainFTraceNode *node, - IRBuilder<>& builder) { - Value *Loaded = builder.CreateLoad(DataPtr); - Value *Print = - builder.CreateSExt(Loaded, IntegerType::get(Loaded->getContext(), 32)); - builder.CreateCall(putchar_func, Print); - if (node->left != (BrainFTraceNode*)~0ULL) - compile_opcode(node->left, builder); - else { - HeaderPHI->addIncoming(DataPtr, builder.GetInsertBlock()); - builder.CreateBr(Header); - } -} - -/// compile_get - Emit code for ',' -void BrainFTraceRecorder::compile_get(BrainFTraceNode *node, - IRBuilder<>& builder) { - Value *Ret = builder.CreateCall(getchar_func); - Value *Trunc = - builder.CreateTrunc(Ret, IntegerType::get(Ret->getContext(), 8)); - builder.CreateStore(Ret, Trunc); - if (node->left != (BrainFTraceNode*)~0ULL) - compile_opcode(node->left, builder); - else { - HeaderPHI->addIncoming(DataPtr, builder.GetInsertBlock()); - builder.CreateBr(Header); - } -} - -/// compile_if - Emit code for '[' -void BrainFTraceRecorder::compile_if(BrainFTraceNode *node, - IRBuilder<>& builder) { - BasicBlock *ZeroChild = 0; - BasicBlock *NonZeroChild = 0; - - IRBuilder<> oldBuilder = builder; - - LLVMContext &Context = Header->getContext(); - - // If both directions of the branch go back to the trace-head, just - // jump there directly. - if (node->left == (BrainFTraceNode*)~0ULL && - node->right == (BrainFTraceNode*)~0ULL) { - HeaderPHI->addIncoming(DataPtr, builder.GetInsertBlock()); - builder.CreateBr(Header); - return; - } - - // Otherwise, there are two cases to handle for each direction: - // ~0ULL - A branch back to the trace head - // 0 - A branch out of the trace - // * - A branch to a node we haven't compiled yet. - // Go ahead and generate code for both targets. - - if (node->left == (BrainFTraceNode*)~0ULL) { - NonZeroChild = Header; - HeaderPHI->addIncoming(DataPtr, builder.GetInsertBlock()); - } else if (node->left == 0) { - NonZeroChild = BasicBlock::Create(Context, - "exit_left_"+utostr(node->pc), - Header->getParent()); - builder.SetInsertPoint(NonZeroChild); - ConstantInt *NewPc = ConstantInt::get(int_type, node->pc+1); - Value *BytecodeIndex = - builder.CreateConstInBoundsGEP1_32(bytecode_array, node->pc+1); - Value *Target = builder.CreateLoad(BytecodeIndex); - CallInst *Call =cast<CallInst>(builder.CreateCall2(Target, NewPc, DataPtr)); - Call->setTailCall(); - builder.CreateRetVoid(); - } else { - NonZeroChild = BasicBlock::Create(Context, - utostr(node->left->pc), - Header->getParent()); - builder.SetInsertPoint(NonZeroChild); - compile_opcode(node->left, builder); - } - - if (node->right == (BrainFTraceNode*)~0ULL) { - ZeroChild = Header; - HeaderPHI->addIncoming(DataPtr, builder.GetInsertBlock()); - } else if (node->right == 0) { - ZeroChild = BasicBlock::Create(Context, - "exit_right_"+utostr(node->pc), - Header->getParent()); - builder.SetInsertPoint(ZeroChild); - ConstantInt *NewPc = ConstantInt::get(int_type, JumpMap[node->pc]+1); - Value *BytecodeIndex = - builder.CreateConstInBoundsGEP1_32(bytecode_array, JumpMap[node->pc]+1); - Value *Target = builder.CreateLoad(BytecodeIndex); - CallInst *Call =cast<CallInst>(builder.CreateCall2(Target, NewPc, DataPtr)); - Call->setTailCall(); - builder.CreateRetVoid(); - } else { - ZeroChild = BasicBlock::Create(Context, - utostr(node->right->pc), - Header->getParent()); - builder.SetInsertPoint(ZeroChild); - compile_opcode(node->right, builder); - } - - // Generate the test and branch to select between the targets. - Value *Loaded = oldBuilder.CreateLoad(DataPtr); - Value *Cmp = oldBuilder.CreateICmpEQ(Loaded, - ConstantInt::get(Loaded->getType(), 0)); - oldBuilder.CreateCondBr(Cmp, ZeroChild, NonZeroChild); -} - -/// compile_back - Emit code for ']' -void BrainFTraceRecorder::compile_back(BrainFTraceNode *node, - IRBuilder<>& builder) { - if (node->right != (BrainFTraceNode*)~0ULL) - compile_opcode(node->right, builder); - else { - HeaderPHI->addIncoming(DataPtr, builder.GetInsertBlock()); - builder.CreateBr(Header); - } -} - -/// compile_opcode - Dispatch to a more specific compiler function based -/// on the opcode of the current node. -void BrainFTraceRecorder::compile_opcode(BrainFTraceNode *node, - IRBuilder<>& builder) { - switch (node->opcode) { - case '+': - compile_plus(node, builder); - break; - case '-': - compile_minus(node, builder); - break; - case '<': - compile_left(node, builder); - break; - case '>': - compile_right(node, builder); - break; - case '.': - compile_put(node, builder); - break; - case ',': - compile_get(node, builder); - break; - case '[': - compile_if(node, builder); - break; - case ']': - compile_back(node, builder); - break; - } -} |