Ignore:
Timestamp:
Mar 7, 2016, 3:37:30 PM (4 years ago)
Author:
nmedfort
Message:

Initial modifications to Pablo Compiler and Kernel Builder to support circular buffers for Lookahead.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/kernels/scanmatchgen.cpp

    r4946 r4959  
    77#include "scanmatchgen.h"
    88#include <llvm/IR/Intrinsics.h>
     9#include <IDISA/idisa_builder.h>
     10#include <llvm/Support/raw_os_ostream.h>
     11
     12using namespace llvm;
    913
    1014Value * generateForwardZeroesMask(IDISA::IDISA_Builder * iBuilder, Value * bits) {
     
    3236    return iBuilder->CreateAnd(bits_minus1, bits);
    3337}
    34        
    35        
    36 void generateScanWordRoutine(Module * m, IDISA::IDISA_Builder * iBuilder, KernelBuilder * kBuilder, int scanwordBitWidth, bool isNameExpression) {
     38
     39Function * generateScanWordRoutine(Module * m, IDISA::IDISA_Builder * iBuilder, unsigned scanwordBitWidth, Type * kernelStuctType, bool isNameExpression) {
     40
     41    Function * function = m->getFunction("scan_matches_in_scanword");
     42    if (LLVM_UNLIKELY(function != nullptr)) {
     43        return function;
     44    }
     45
    3746    LLVMContext & ctxt = m->getContext();
    38     Type * T = iBuilder->getIntNTy(scanwordBitWidth);   
     47    Type * T = iBuilder->getIntNTy(scanwordBitWidth);
    3948    Type * S = PointerType::get(iBuilder->getIntNTy(8), 0);
    4049    Type * returnType = StructType::get(ctxt, std::vector<Type *>({T, T}));
    41     Type * kernelStuctType = PointerType::get(kBuilder->getKernelStructType(), 0);
    4250    FunctionType * functionType = FunctionType::get(returnType, std::vector<Type *>({kernelStuctType, T, T, T, T, T}), false);
    43     Function * sFunction;
    44        
     51
    4552    SmallVector<AttributeSet, 6> Attrs;
    4653    Attrs.push_back(AttributeSet::get(ctxt, ~0U, std::vector<Attribute::AttrKind>({ Attribute::NoUnwind, Attribute::UWTable })));
     
    5158    Attrs.push_back(AttributeSet::get(ctxt, 5, std::vector<Attribute::AttrKind>({})));
    5259    AttributeSet AttrSet = AttributeSet::get(ctxt, Attrs);
    53    
    54     sFunction = Function::Create(functionType, GlobalValue::ExternalLinkage, "scan_matches_in_scanword", m);
    55     sFunction->setCallingConv(CallingConv::C);
    56     sFunction->setAttributes(AttrSet);
    57     sFunction->addFnAttr(llvm::Attribute::AlwaysInline);
    58        
    59     Function::arg_iterator args = sFunction->arg_begin();
     60
     61    function = Function::Create(functionType, GlobalValue::ExternalLinkage, "scan_matches_in_scanword", m);
     62    function->setCallingConv(CallingConv::C);
     63    function->setAttributes(AttrSet);
     64    function->addFnAttr(llvm::Attribute::AlwaysInline);
     65
     66    Function::arg_iterator args = function->arg_begin();
    6067    Value * this_input_parm = args++;
    6168    this_input_parm->setName("this");
     
    7582    else
    7683        matchProcessor = m->getOrInsertFunction("wrapped_report_match", Type::getVoidTy(ctxt), T, T, T, S, T, S, nullptr);
    77    
    78     iBuilder->SetInsertPoint(BasicBlock::Create(ctxt, "entry", sFunction,0));
     84
     85    iBuilder->SetInsertPoint(BasicBlock::Create(ctxt, "entry", function,0));
    7986
    8087    BasicBlock * entry_block = iBuilder->GetInsertBlock();
    81     BasicBlock * matches_test_block = BasicBlock::Create(ctxt, "matches_test_block", sFunction, 0);
    82     BasicBlock * process_matches_loop_entry = BasicBlock::Create(ctxt, "process_matches_loop", sFunction, 0);
    83     BasicBlock * prior_breaks_block = BasicBlock::Create(ctxt, "prior_breaks_block", sFunction, 0);
    84     BasicBlock * loop_final_block = BasicBlock::Create(ctxt, "loop_final_block", sFunction, 0);
    85     BasicBlock * matches_done_block = BasicBlock::Create(ctxt, "matches_done_block", sFunction, 0);
    86     BasicBlock * remaining_breaks_block = BasicBlock::Create(ctxt, "remaining_breaks_block", sFunction, 0);
    87     BasicBlock * return_block = BasicBlock::Create(ctxt, "return_block", sFunction, 0);
    88        
    89        
     88    BasicBlock * matches_test_block = BasicBlock::Create(ctxt, "matches_test_block", function, 0);
     89    BasicBlock * process_matches_loop_entry = BasicBlock::Create(ctxt, "process_matches_loop", function, 0);
     90    BasicBlock * prior_breaks_block = BasicBlock::Create(ctxt, "prior_breaks_block", function, 0);
     91    BasicBlock * loop_final_block = BasicBlock::Create(ctxt, "loop_final_block", function, 0);
     92    BasicBlock * matches_done_block = BasicBlock::Create(ctxt, "matches_done_block", function, 0);
     93    BasicBlock * remaining_breaks_block = BasicBlock::Create(ctxt, "remaining_breaks_block", function, 0);
     94    BasicBlock * return_block = BasicBlock::Create(ctxt, "return_block", function, 0);
     95
     96
    9097    // The match scanner works with a loop involving four variables:
    9198    // (a) the bit stream scanword of matches marking the ends of selected records,
    9299    // (b) the bit stream scanword of record_breaks marking the ends of all records,
    93     // (c) the integer lastRecordNum indicating the number of records processed so far, 
     100    // (c) the integer lastRecordNum indicating the number of records processed so far,
    94101    // (d) the index lastRecordStart indicating the file position of the last record.
    95102    // We set up a loop structure, in which a set of 4 phi nodes initialize these
     
    97104    // the loop body.
    98105
    99    
     106
    100107    iBuilder->CreateBr(matches_test_block);
    101108
    102     // LOOP Test Block 
     109    // LOOP Test Block
    103110    iBuilder->SetInsertPoint(matches_test_block);
    104111    PHINode * matches_phi = iBuilder->CreatePHI(T, 2, "matches");
     
    112119    Value * have_matches_cond = iBuilder->CreateICmpNE(matches_phi, ConstantInt::get(T, 0));
    113120    iBuilder->CreateCondBr(have_matches_cond, process_matches_loop_entry, matches_done_block);
    114    
     121
    115122    // LOOP BODY
    116123    // The loop body is entered if we have more matches to process.
    117124    iBuilder->SetInsertPoint(process_matches_loop_entry);
    118125    Value * prior_breaks = iBuilder->CreateAnd(generateForwardZeroesMask(iBuilder, matches_phi), record_breaks_phi);
    119     // Within the loop we have a conditional block that is executed if there are any prior 
     126    // Within the loop we have a conditional block that is executed if there are any prior
    120127    // record breaks.
    121128    Value * prior_breaks_cond = iBuilder->CreateICmpNE(prior_breaks, ConstantInt::get(T, 0));
     
    130137    Value * matchRecordStart = iBuilder->CreateAdd(scanwordPos, iBuilder->CreateSub(width, reverseDistance));
    131138    iBuilder->CreateBr(loop_final_block);
    132    
     139
    133140    // LOOP FINAL BLOCK
    134141    // The prior breaks, if any have been counted.  Set up phi nodes for the recordNum
     
    143150    Value * matchRecordEnd = iBuilder->CreateAdd(scanwordPos, generateCountForwardZeroes(iBuilder, matches_phi));
    144151
    145     Value* filebufptr = kBuilder->getKernelInternalState(this_input_parm, 7);
    146     Value* filesize = kBuilder->getKernelInternalState(this_input_parm, 8);
    147     Value* filenameptr = kBuilder->getKernelInternalState(this_input_parm, 9);
     152    Value* filebuf_gep = iBuilder->CreateGEP(this_input_parm, {iBuilder->getInt64(0), iBuilder->getInt32(0), iBuilder->getInt32(7)});
     153    Value* filebufptr = iBuilder->CreateLoad(filebuf_gep, "filebuf");
     154
     155    Value* filesize_gep = iBuilder->CreateGEP(this_input_parm, {iBuilder->getInt64(0), iBuilder->getInt32(0), iBuilder->getInt32(8)});
     156    Value* filesize = iBuilder->CreateLoad(filesize_gep, "filensize");
     157
     158    Value* filename_gep = iBuilder->CreateGEP(this_input_parm, {iBuilder->getInt64(0), iBuilder->getInt32(0), iBuilder->getInt32(9)});
     159    Value* filenameptr = iBuilder->CreateLoad(filename_gep, "filename");
    148160
    149161    if(isNameExpression)
     
    158170    recordStart_phi->addIncoming(matchRecordStart_phi, loop_final_block);
    159171    iBuilder->CreateBr(matches_test_block);
    160    
    161    
     172
     173
    162174    // LOOP EXIT/MATCHES_DONE
    163175    iBuilder->SetInsertPoint(matches_done_block);
     
    165177    Value * more_breaks_cond = iBuilder->CreateICmpNE(record_breaks_phi, ConstantInt::get(T, 0));
    166178    iBuilder->CreateCondBr(more_breaks_cond, remaining_breaks_block, return_block);
    167    
     179
    168180    // REMAINING_BREAKS_BLOCK: process remaining record breaks after all matches are processed
    169181    iBuilder->SetInsertPoint(remaining_breaks_block);
     
    173185    Value * pendingLineStart = iBuilder->CreateAdd(scanwordPos, iBuilder->CreateSub(width, reverseZeroes));
    174186    iBuilder->CreateBr(return_block);
    175    
     187
    176188    // RETURN block
    177189    iBuilder->SetInsertPoint(return_block);
     
    186198    retVal = iBuilder->CreateInsertValue(retVal, finalRecordCount_phi, 1);
    187199    iBuilder->CreateRet(retVal);
    188    
    189 }
    190 
    191 
    192 void generateScanMatch(Module * m, IDISA::IDISA_Builder * iBuilder, int scanwordBitWidth, KernelBuilder * kBuilder, bool isNameExpression){
    193    
    194    
    195     Type * T = iBuilder->getIntNTy(scanwordBitWidth);
     200
     201    return function;
     202}
     203
     204
     205void generateScanMatch(Module * m, IDISA::IDISA_Builder * iBuilder, unsigned scanWordBitWidth, KernelBuilder * kBuilder, bool isNameExpression){
     206
     207
     208    Type * T = iBuilder->getIntNTy(scanWordBitWidth);
    196209    Type * S = PointerType::get(iBuilder->getIntNTy(8), 0);
    197     int fieldCount = iBuilder->getBitBlockWidth()/scanwordBitWidth;
     210    const unsigned fieldCount = iBuilder->getBitBlockWidth() / scanWordBitWidth;
    198211    Type * scanwordVectorType =  VectorType::get(T, fieldCount);
    199212
    200     kBuilder->addKernelInputStream(1, "matches");
    201     kBuilder->addKernelInputStream(1, "breaks");
     213    kBuilder->addInputStream(1, "matches");
     214    kBuilder->addInputStream(1, "breaks");
    202215    //use index
    203     int blockPosIdx = kBuilder->extendKernelInternalStateType(T);
    204     int lineStartIdx = kBuilder->extendKernelInternalStateType(T);
    205     int lineNumIdx = kBuilder->extendKernelInternalStateType(T);
    206     kBuilder->extendKernelInternalStateType(S);
    207     kBuilder->extendKernelInternalStateType(T);
    208     kBuilder->extendKernelInternalStateType(S);
    209 
    210     int segBlocks = kBuilder->getSegmentBlocks();
    211 
    212     kBuilder->PrepareDoBlockFunction();
    213 
    214     generateScanWordRoutine(m, iBuilder, kBuilder, scanwordBitWidth, isNameExpression);
    215 
    216     struct Inputs inputs = kBuilder->openDoBlock();
    217     struct Outputs outputs;   
     216    unsigned blockPosIdx = kBuilder->addInternalStateType(T);
     217    unsigned lineStartIdx = kBuilder->addInternalStateType(T);
     218    unsigned lineNumIdx = kBuilder->addInternalStateType(T);
     219    kBuilder->addInternalStateType(S);
     220    kBuilder->addInternalStateType(T);
     221    kBuilder->addInternalStateType(S);
     222
     223    Function * function = kBuilder->prepareFunction();
     224
     225    Type * kernelStuctType = PointerType::get(kBuilder->getKernelStructType(), 0);
     226
     227    Function * scanWordFunction = generateScanWordRoutine(m, iBuilder, scanWordBitWidth, kernelStuctType, isNameExpression);
     228
     229    iBuilder->SetInsertPoint(&function->getEntryBlock());
     230
    218231    Value * kernelStuctParam = kBuilder->getKernelStructParam();
    219    
    220     Value * scanwordPos = kBuilder->getKernelInternalState(kernelStuctParam, blockPosIdx);
    221     Value * recordStart = kBuilder->getKernelInternalState(kernelStuctParam, lineStartIdx);
    222     Value * recordNum = kBuilder->getKernelInternalState(kernelStuctParam, lineNumIdx);
     232
     233    Value * scanwordPos = iBuilder->CreateBlockAlignedLoad(kBuilder->getInternalState(blockPosIdx));
     234    Value * recordStart = iBuilder->CreateBlockAlignedLoad(kBuilder->getInternalState(lineStartIdx));
     235    Value * recordNum = iBuilder->CreateBlockAlignedLoad(kBuilder->getInternalState(lineNumIdx));
    223236    Value * wordResult = nullptr;
    224237
    225     Function * wordScanFcn = m->getFunction("scan_matches_in_scanword");
    226     for(int j=0; j<segBlocks; j++){
    227         Value * matchWordVector = iBuilder->CreateBitCast(inputs.streams[j][0], scanwordVectorType);
    228         Value * breakWordVector = iBuilder->CreateBitCast(inputs.streams[j][1], scanwordVectorType);
    229         for(int i=0; i<segBlocks*iBuilder->getBitBlockWidth()/scanwordBitWidth; i++){
    230 
     238    const unsigned segmentBlocks = kBuilder->getSegmentBlocks();
     239    const unsigned scanWordBlocks =  segmentBlocks * fieldCount;
     240
     241    for(unsigned j = 0; j < segmentBlocks; ++j) {
     242
     243        Value * matchWordVector = iBuilder->CreateBitCast(iBuilder->CreateBlockAlignedLoad(kBuilder->getInputStream(0)), scanwordVectorType);
     244        Value * breakWordVector = iBuilder->CreateBitCast(iBuilder->CreateBlockAlignedLoad(kBuilder->getInputStream(1)), scanwordVectorType);
     245
     246        for(unsigned i = 0; i < scanWordBlocks; ++i){
    231247            Value * matchWord = iBuilder->CreateExtractElement(matchWordVector, ConstantInt::get(T, i));
    232248            Value * recordBreaksWord = iBuilder->CreateExtractElement(breakWordVector, ConstantInt::get(T, i));
    233             wordResult = iBuilder->CreateCall(wordScanFcn, std::vector<Value *>({kernelStuctParam, matchWord, recordBreaksWord, scanwordPos, recordStart, recordNum}));
    234             scanwordPos = iBuilder->CreateAdd(scanwordPos, ConstantInt::get(T, scanwordBitWidth));
     249            wordResult = iBuilder->CreateCall(scanWordFunction, std::vector<Value *>({kernelStuctParam, matchWord, recordBreaksWord, scanwordPos, recordStart, recordNum}));
     250            scanwordPos = iBuilder->CreateAdd(scanwordPos, ConstantInt::get(T, scanWordBitWidth));
    235251            recordStart = iBuilder->CreateExtractValue(wordResult, std::vector<unsigned>({0}));
    236252            recordNum = iBuilder->CreateExtractValue(wordResult, std::vector<unsigned>({1}));
    237253        }
     254        kBuilder->increment();
    238255    }
    239256
    240     kBuilder->changeKernelInternalState(kernelStuctParam, blockPosIdx, scanwordPos);
    241     kBuilder->changeKernelInternalState(kernelStuctParam, lineStartIdx, recordStart);
    242     kBuilder->changeKernelInternalState(kernelStuctParam, lineNumIdx, recordNum);
    243 
    244     kBuilder->closeDoBlock(outputs);
    245 
    246     kBuilder->finalizeMethods();
    247 }
    248 
    249 
    250 
     257    kBuilder->setInternalState(blockPosIdx, scanwordPos);
     258    kBuilder->setInternalState(lineStartIdx, recordStart);
     259    kBuilder->setInternalState(lineNumIdx, recordNum);
     260
     261    kBuilder->finalize();
     262}
Note: See TracChangeset for help on using the changeset viewer.