美文网首页
[LLVM_IR]GenerateIfElseIR

[LLVM_IR]GenerateIfElseIR

作者: HAPPYers | 来源:发表于2019-09-29 20:45 被阅读0次
    #include "llvm/IR/IRBuilder.h"
    #include "llvm/IR/LLVMContext.h"
    #include "llvm/IR/Module.h"
    #include "llvm/IR/Verifier.h"
    #include <vector>
    using namespace llvm;
    
    static LLVMContext Context;
    static Module* ModuleOb = new Module ( "my compiler", Context );
    static std::vector<std::string> FunArgs;
    typedef SmallVector<BasicBlock*, 16> BBList;
    typedef SmallVector<Value*, 16> ValList;
    
    Function* createFunc ( IRBuilder<>& Builder, std::string Name ) {
        std::vector<Type*> Integers ( FunArgs.size(), Type::getInt32Ty ( Context ) );
        FunctionType* funcType =
            llvm::FunctionType::get ( Builder.getInt32Ty(), Integers, false );
        Function* fooFunc = llvm::Function::Create (
                funcType, llvm::Function::ExternalLinkage, Name, ModuleOb );
        return fooFunc;
    }
    
    void setFuncArgs ( Function* fooFunc, std::vector<std::string> FunArgs ) {
        unsigned Idx = 0;
        Function::arg_iterator AI, AE;
    
        for ( AI = fooFunc->arg_begin(), AE = fooFunc->arg_end(); AI != AE;
            ++AI, ++Idx )
            AI->setName ( FunArgs[Idx] );
    }
    
    BasicBlock* createBB ( Function* fooFunc, std::string Name ) {
        return BasicBlock::Create ( Context, Name, fooFunc );
    }
    
    GlobalVariable* createGlob ( IRBuilder<>& Builder, std::string Name ) {
        ModuleOb->getOrInsertGlobal ( Name, Builder.getInt32Ty() );
        GlobalVariable* gVar = ModuleOb->getNamedGlobal ( Name );
        gVar->setLinkage ( GlobalValue::CommonLinkage );
        gVar->setAlignment ( 4 );
        return gVar;
    }
    
    Value* createArith ( IRBuilder<>& Builder, Value* L, Value* R ) {
        return Builder.CreateMul ( L, R, "multmp" );
    }
    
    Value* createIfElse ( IRBuilder<>& Builder, BBList List, ValList VL ) {
        Value* Condtn = VL[0];
        Value* Arg1 = VL[1];
        BasicBlock* ThenBB = List[0];
        BasicBlock* ElseBB = List[1];
        BasicBlock* MergeBB = List[2];
        Builder.CreateCondBr ( Condtn, ThenBB, ElseBB );
        Builder.SetInsertPoint ( ThenBB );
        Value* ThenVal = Builder.CreateAdd ( Arg1, Builder.getInt32 ( 1 ), "thenaddtmp" );
        Builder.CreateBr ( MergeBB );
        Builder.SetInsertPoint ( ElseBB );
        Value* ElseVal = Builder.CreateAdd ( Arg1, Builder.getInt32 ( 2 ), "elseaddtmp" );
        Builder.CreateBr ( MergeBB );
        unsigned PhiBBSize = List.size() - 1;
        Builder.SetInsertPoint ( MergeBB );
        PHINode* Phi = Builder.CreatePHI ( Type::getInt32Ty ( Context ),
                PhiBBSize, "iftmp" );
        Phi->addIncoming ( ThenVal, ThenBB );
        Phi->addIncoming ( ElseVal, ElseBB );
        return Phi;
    }
    
    int main ( int argc, char* argv[] ) {
        FunArgs.push_back ( "a" );
        FunArgs.push_back ( "b" );
        static IRBuilder<> Builder ( Context );
        GlobalVariable* gVar = createGlob ( Builder, "x" );
        Function* fooFunc = createFunc ( Builder, "foo" );
        setFuncArgs ( fooFunc, FunArgs );
        BasicBlock* entry = createBB ( fooFunc, "entry" );
        Builder.SetInsertPoint ( entry );
        Function::arg_iterator Args = fooFunc->arg_begin();
        Value* Arg1 = &*Args++;
        Value* constant = Builder.getInt32 ( 16 );
        Value* val = createArith ( Builder, Arg1, constant );
        Value* val2 = Builder.getInt32 ( 100 );
        Value* Compare = Builder.CreateICmpULT ( val, val2, "cmptmp" );
        // Value *Condtn = Builder.CreateICmpNE(Compare, Builder.getInt32(0),
        // "ifcond");
        ValList VL;
        VL.push_back ( Compare );
        VL.push_back ( Arg1 );
        BasicBlock* ThenBB = createBB ( fooFunc, "then" );
        BasicBlock* ElseBB = createBB ( fooFunc, "else" );
        BasicBlock* MergeBB = createBB ( fooFunc, "ifcont" );
        BBList List;
        List.push_back ( ThenBB );
        List.push_back ( ElseBB );
        List.push_back ( MergeBB );
        Value* v = createIfElse ( Builder, List, VL );
        Builder.CreateRet ( v );
        verifyFunction ( *fooFunc );
        ModuleOb->dump();
        return 0;
    }
    

    相关文章

      网友评论

          本文标题:[LLVM_IR]GenerateIfElseIR

          本文链接:https://www.haomeiwen.com/subject/lpsqpctx.html