Ignore:
Timestamp:
Jul 18, 2015, 10:18:34 AM (4 years ago)
Author:
nmedfort
Message:

First attempt to intergrate 'generate_predefined_ucd_functions' into build process.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/pablo/pablo_compiler.cpp

    r4682 r4684  
    6868PabloCompiler::PabloCompiler()
    6969: mMod(nullptr)
     70, mExecutionEngine(nullptr)
    7071, mBuilder(nullptr)
    7172, mCarryManager(nullptr)
     73, mCarryOffset(0)
    7274, mBitBlockType(VectorType::get(IntegerType::get(getGlobalContext(), 64), BLOCK_SIZE / 64))
    7375, iBuilder(mBitBlockType)
     
    8991}
    9092   
    91 void PabloCompiler::InstallExternalFunction(std::string C_fn_name, void * fn_ptr, const size_t carrySize) {
    92     mExternalMap.insert(std::make_pair(C_fn_name, fn_ptr));
    93 }
    9493
    9594void PabloCompiler::genPrintRegister(std::string regName, Value * bitblockValue) {
     
    128127    #endif
    129128    builder.setOptLevel(mMaxWhileDepth ? CodeGenOpt::Level::Less : CodeGenOpt::Level::None);
    130     ExecutionEngine * engine = builder.create();
    131     if (engine == nullptr) {
     129    mExecutionEngine = builder.create();
     130    if (mExecutionEngine == nullptr) {
    132131        throw std::runtime_error("Could not create ExecutionEngine: " + errMessage);
    133132    }
    134     DeclareFunctions(engine);
    135     DeclareCallFunctions(engine);
     133    DeclareFunctions();
    136134
    137135    auto func = compile(function, mMod);
     
    144142    verifyModule(*module, &dbgs());
    145143
    146     engine->finalizeObject();
     144    mExecutionEngine->finalizeObject();
     145    ExecutionEngine * engine = mExecutionEngine;
     146    mExecutionEngine = nullptr; // <-- pass ownership of the execution engine to the caller
    147147
    148148    return CompiledPabloFunction(func.second, func.first, engine);
     
    176176    }
    177177       
    178     unsigned totalCarryDataSize = mCarryManager->initialize(&(function.getEntryBlock()), mCarryDataPtr);
     178    mCarryOffset = mCarryManager->initialize(&(function.getEntryBlock()), mCarryDataPtr);
    179179   
    180180    //Generate the IR instructions for the function.
     
    202202
    203203    //Return the required size of the carry data area to the process_block function.
    204     return std::make_pair(mFunction, totalCarryDataSize * sizeof(BitBlock));
     204    return std::make_pair(mFunction, mCarryOffset * sizeof(BitBlock));
    205205}
    206206
     
    348348}
    349349
    350 inline void PabloCompiler::DeclareFunctions(ExecutionEngine * const engine) {
     350inline void PabloCompiler::DeclareFunctions() {
    351351    if (DumpTrace || TraceNext) {
    352352        //This function can be used for testing to print the contents of a register from JIT'd code to the terminal window.
    353353        mPrintRegisterFunction = mMod->getOrInsertFunction("wrapped_print_register", Type::getVoidTy(mMod->getContext()), Type::getInt8PtrTy(mMod->getContext()), mBitBlockType, NULL);
    354         if (engine) engine->addGlobalMapping(cast<GlobalValue>(mPrintRegisterFunction), (void *)&wrapped_print_register);
    355     }
    356 }
    357    
    358 void PabloCompiler::DeclareCallFunctions(ExecutionEngine * const engine) {
    359     for (auto mapping : mCalleeMap) {
    360         const String * callee = mapping.first;
    361         auto ei = mExternalMap.find(callee->value());
    362         if (ei != mExternalMap.end()) {
    363 
    364             Type * inputType = PointerType::get(StructType::get(mMod->getContext(), std::vector<Type *>{8, mBitBlockType}), 0);
    365             Type * carryType = PointerType::get(mBitBlockType, 0);
    366             Type * outputType = PointerType::get(StructType::get(mMod->getContext(), std::vector<Type *>{1, mBitBlockType}), 0);
    367             FunctionType * functionType = FunctionType::get(Type::getVoidTy(mMod->getContext()), std::vector<Type *>{inputType, carryType, outputType}, false);
    368 
    369             //Starts on process_block
    370             SmallVector<AttributeSet, 3> Attrs;
    371             Attrs.push_back(AttributeSet::get(mMod->getContext(), 1U, { Attribute::ReadOnly, Attribute::NoCapture }));
    372             Attrs.push_back(AttributeSet::get(mMod->getContext(), 2U, { Attribute::NoCapture }));
    373             Attrs.push_back(AttributeSet::get(mMod->getContext(), 3U, { Attribute::ReadNone, Attribute::NoCapture }));
    374             AttributeSet AttrSet = AttributeSet::get(mMod->getContext(), Attrs);
    375 
    376             Function * externalFunction = cast<Function>(mMod->getOrInsertFunction(callee->value(), functionType, AttrSet));
    377             if (LLVM_UNLIKELY(externalFunction == nullptr)) {
    378                 throw std::runtime_error("Could not create static method call for external function \"" + callee->to_string() + "\"");
    379             }
    380             externalFunction->setCallingConv(llvm::CallingConv::C);
    381 
    382             if (engine) engine->addGlobalMapping(externalFunction, ei->second);
    383             mCalleeMap[callee] = externalFunction;
    384         }
    385         else {
    386             throw std::runtime_error("External function \"" + callee->to_string() + "\" not installed");
    387         }
     354        if (mExecutionEngine) mExecutionEngine->addGlobalMapping(cast<GlobalValue>(mPrintRegisterFunction), (void *)&wrapped_print_register);
    388355    }
    389356}
     
    583550            return;
    584551        }
    585         auto ci = mCalleeMap.find(call->getCallee());
    586         if (LLVM_UNLIKELY(ci == mCalleeMap.end())) {
    587             throw std::runtime_error("Unexpected error locating static function for \"" + call->getCallee()->to_string() + "\"");
    588         }       
    589 
    590         Function * function = ci->second;
    591         auto arg = function->getArgumentList().begin();
    592         Value * carryFramePtr = ConstantPointerNull::get(cast<PointerType>((++arg)->getType()));
    593         AllocaInst * outputStruct = mBuilder->CreateAlloca(cast<PointerType>((++arg)->getType())->getElementType());
    594         mBuilder->CreateCall3(function, mInputAddressPtr, carryFramePtr, outputStruct);
     552
     553        const Prototype * proto = call->getPrototype();
     554        const String * callee = proto->getName();
     555
     556        Type * inputType = StructType::get(mMod->getContext(), std::vector<Type *>{proto->getNumOfParameters(), mBitBlockType});
     557        Type * carryType = mBitBlockType;
     558        Type * outputType = StructType::get(mMod->getContext(), std::vector<Type *>{proto->getNumOfResults(), mBitBlockType});
     559        FunctionType * functionType = FunctionType::get(Type::getVoidTy(mMod->getContext()), std::vector<Type *>{PointerType::get(inputType, 0), PointerType::get(carryType, 0), PointerType::get(outputType, 0)}, false);
     560
     561        //Starts on process_block
     562        SmallVector<AttributeSet, 3> Attrs;
     563        Attrs.push_back(AttributeSet::get(mMod->getContext(), 1U, { Attribute::ReadOnly, Attribute::NoCapture }));
     564        Attrs.push_back(AttributeSet::get(mMod->getContext(), 2U, { Attribute::NoCapture }));
     565        Attrs.push_back(AttributeSet::get(mMod->getContext(), 3U, { Attribute::ReadNone, Attribute::NoCapture }));
     566        AttributeSet AttrSet = AttributeSet::get(mMod->getContext(), Attrs);
     567
     568        Function * externalFunction = cast<Function>(mMod->getOrInsertFunction(callee->value(), functionType, AttrSet));
     569        if (LLVM_UNLIKELY(externalFunction == nullptr)) {
     570            throw std::runtime_error("Could not create static method call for external function \"" + callee->to_string() + "\"");
     571        }
     572        externalFunction->setCallingConv(llvm::CallingConv::C);
     573
     574        if (mExecutionEngine) mExecutionEngine->addGlobalMapping(externalFunction, proto->getFunctionPtr());
     575
     576        // add mCarryOffset to mCarryDataPtr
     577        Value * carryFramePtr = mBuilder->CreateGEP(mCarryDataPtr, mBuilder->getInt64(mCarryOffset));
     578        AllocaInst * outputStruct = mBuilder->CreateAlloca(outputType);
     579        mBuilder->CreateCall3(externalFunction, mInputAddressPtr, carryFramePtr, outputStruct);
    595580        Value * outputPtr = mBuilder->CreateGEP(outputStruct, { mBuilder->getInt32(0), mBuilder->getInt32(0) });
    596581        expr = mBuilder->CreateAlignedLoad(outputPtr, BLOCK_SIZE / 8, false);
     582
     583        mCarryOffset += (proto->getRequiredStateSpace() + (BLOCK_SIZE / 8) - 1) / (BLOCK_SIZE / 8);
    597584    }
    598585    else if (const And * pablo_and = dyn_cast<And>(stmt)) {
     
    796783   
    797784void PabloCompiler::SetOutputValue(Value * marker, const unsigned index) {
    798     assert (marker);
    799     if (marker->getType()->isPointerTy()) {
     785    if (LLVM_UNLIKELY(marker == nullptr)) {
     786        throw std::runtime_error("Cannot set result " + std::to_string(index) + " to Null");
     787    }
     788    if (LLVM_UNLIKELY(marker->getType()->isPointerTy())) {
    800789        marker = mBuilder->CreateAlignedLoad(marker, BLOCK_SIZE/8, false);
    801790    }
Note: See TracChangeset for help on using the changeset viewer.