Ignore:
Timestamp:
Jan 27, 2017, 2:22:06 PM (2 years ago)
Author:
nmedfort
Message:

Optimized Symbol Generation (and fixed potential bug that could allow duplicate names being constructed); made PabloKernel? extend PabloAST (temporarily removed PabloAST::getName() to avoid diamond problem); added an internal scalar to PabloKernel? struct for each Count to avoid InOut? output scalar variable problem; allowed CodeMotionPass? to move code within the same scope but across a branch statement. Began work on separating Kernels into either Block-Oriented or Segment-Oriented kernels.

File:
1 edited

Legend:

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

    r5270 r5283  
    3535using TypeId = PabloAST::ClassTypeId;
    3636
     37inline static unsigned getAlignment(const Value * const ptr) {
     38    return ptr->getType()->getPrimitiveSizeInBits() / 8;
     39}
     40
     41inline static unsigned getPointerElementAlignment(const Value * const ptr) {
     42    return ptr->getType()->getPointerElementType()->getPrimitiveSizeInBits() / 8;
     43}
     44
    3745void PabloCompiler::initializeKernelData() {
    3846    Examine();
     
    5260     
    5361    PabloBlock * const entryBlock = mKernel->getEntryBlock(); assert (entryBlock);
    54     mMarkerMap.emplace(entryBlock->createZeroes(), iBuilder->allZeroes());
    55     mMarkerMap.emplace(entryBlock->createOnes(), iBuilder->allOnes());
     62    mMarker.emplace(entryBlock->createZeroes(), iBuilder->allZeroes());
     63    mMarker.emplace(entryBlock->createOnes(), iBuilder->allOnes());
    5664
    5765    Value * const blockNo = mKernel->getScalarField(mSelf, blockNoScalar);
     
    5967    for (unsigned i = 0; i < mKernel->getNumOfInputs(); ++i) {
    6068        Var * var = mKernel->getInput(i);
    61         std::string name = var->getName()->to_string();
     69        std::string name = var->getName().str();
    6270        Value * input = nullptr;
    6371        if (var->getType()->isSingleValueType()) {
     
    6674            input = mKernel->getStreamSetPtr(mSelf, name, blockNo);
    6775        }
    68         mMarkerMap.emplace(var, input);
     76        mMarker.emplace(var, input);
    6977    }
    7078
    7179    for (unsigned i = 0; i < mKernel->getNumOfOutputs(); ++i) {
    7280        Var * var = mKernel->getOutput(i);
    73         std::string name = var->getName()->to_string();
     81        std::string name = var->getName().str();
    7482        Value * output = nullptr;
    7583        if (var->getType()->isSingleValueType()) {
     
    7886            output = mKernel->getStreamSetPtr(mSelf, name, blockNo);
    7987        }
    80         mMarkerMap.emplace(var, output);
     88        mMarker.emplace(var, output);
    8189    }
    8290
    8391    compileBlock(entryBlock);
    8492
    85     #ifdef PRINT_TIMING_INFORMATION
    86     const timestamp_t pablo_compilation_end = read_cycle_counter();
    87     std::cerr << "PABLO COMPILATION TIME: " << (pablo_compilation_end - pablo_compilation_start) << std::endl;
    88     #endif
    8993}
    9094
     
    103107        } else if (LLVM_UNLIKELY(isa<Branch>(stmt))) {
    104108            Examine(cast<Branch>(stmt)->getBody());
     109        } else if (LLVM_UNLIKELY(isa<Count>(stmt))) {
     110            mAccumulator.insert(std::make_pair(stmt, iBuilder->getInt32(mKernel->addUnnamedScalar(stmt->getType()))));
    105111        }
    106112    }   
     
    111117        compileStatement(statement);
    112118    }
    113 }
    114 
    115 static const llvm::StringRef EmptyString;
    116 
    117 inline const llvm::StringRef & getName(const PabloAST * expr) {
    118     if (expr->getName()) {
    119         return expr->getName()->value();
    120     }
    121     return EmptyString;
    122119}
    123120
     
    148145
    149146    for (const Var * var : ifStatement->getEscaped()) {
    150         auto f = mMarkerMap.find(var);
    151         if (LLVM_UNLIKELY(f == mMarkerMap.end())) {
     147        auto f = mMarker.find(var);
     148        if (LLVM_UNLIKELY(f == mMarker.end())) {
    152149            std::string tmp;
    153150            raw_string_ostream out(tmp);
     
    189186
    190187    for (const auto i : incoming) {
    191         const Var * var; Value * value;
    192         std::tie(var, value) = i;
    193 
    194         auto f = mMarkerMap.find(var);
    195         if (LLVM_UNLIKELY(f == mMarkerMap.end() || f->second == value)) {
     188        const Var * var; Value * incoming;
     189        std::tie(var, incoming) = i;
     190
     191        auto f = mMarker.find(var);
     192        if (LLVM_UNLIKELY(f == mMarker.end())) {
    196193            std::string tmp;
    197194            raw_string_ostream out(tmp);
     195            out << "PHINode creation error: ";
    198196            var->print(out);
    199             out << " was not assigned a value.";
     197            out << " was not assigned an outgoing value.";
    200198            llvm::report_fatal_error(out.str());
    201199        }
    202200
    203         Value * const next = f->second;
    204 
    205         assert (value->getType() == next->getType());
    206 
    207         PHINode * phi = iBuilder->CreatePHI(value->getType(), 2, getName(var));
    208         phi->addIncoming(value, ifEntryBlock);
    209         phi->addIncoming(next, ifExitBlock);
     201        Value * const outgoing = f->second;
     202        if (LLVM_UNLIKELY(incoming == outgoing)) {
     203            continue;
     204        }
     205
     206        if (LLVM_UNLIKELY(incoming->getType() != outgoing->getType())) {
     207            std::string tmp;
     208            raw_string_ostream out(tmp);
     209            out << "PHINode creation error: incoming type of ";
     210            var->print(out);
     211            out << " (";
     212            incoming->getType()->print(out);
     213            out << ") differs from the outgoing type (";
     214            outgoing->getType()->print(out);
     215            out << ") within ";
     216            ifStatement->print(out);
     217            llvm::report_fatal_error(out.str());
     218        }
     219
     220        PHINode * phi = iBuilder->CreatePHI(incoming->getType(), 2, var->getName());
     221        phi->addIncoming(incoming, ifEntryBlock);
     222        phi->addIncoming(outgoing, ifExitBlock);
    210223        f->second = phi;
    211 
    212         assert (mMarkerMap[var] == phi);
    213224    }   
    214225}
     
    252263    // for any Next nodes in the loop body, initialize to (a) pre-loop value.
    253264    for (const auto var : escaped) {
    254         auto f = mMarkerMap.find(var);
    255         if (LLVM_UNLIKELY(f == mMarkerMap.end())) {
     265        auto f = mMarker.find(var);
     266        if (LLVM_UNLIKELY(f == mMarker.end())) {
    256267            std::string tmp;
    257268            raw_string_ostream out(tmp);
     269            out << "PHINode creation error: ";
    258270            var->print(out);
    259271            out << " is uninitialized prior to entering ";
     
    262274        }
    263275        Value * entryValue = f->second;
    264         PHINode * phi = iBuilder->CreatePHI(entryValue->getType(), 2, getName(var));
     276        PHINode * phi = iBuilder->CreatePHI(entryValue->getType(), 2, var->getName());
    265277        phi->addIncoming(entryValue, whileEntryBlock);
    266278        f->second = phi;
    267         assert(mMarkerMap[var] == phi);
     279        assert(mMarker[var] == phi);
    268280        variants.emplace_back(var, phi);
    269281    }
     
    302314    // and for any variant nodes in the loop body
    303315    for (const auto variant : variants) {
    304         const Var * var; PHINode * phi;
    305         std::tie(var, phi) = variant;
    306         const auto f = mMarkerMap.find(var);
    307         if (LLVM_UNLIKELY(f == mMarkerMap.end() || f->second == phi)) {
     316        const Var * var; PHINode * incomingPhi;
     317        std::tie(var, incomingPhi) = variant;
     318        const auto f = mMarker.find(var);
     319        if (LLVM_UNLIKELY(f == mMarker.end())) {
    308320            std::string tmp;
    309321            raw_string_ostream out(tmp);
     322            out << "PHINode creation error: ";
    310323            var->print(out);
    311             out << " was not assigned a value.";
     324            out << " is no longer assigned a value.";
    312325            llvm::report_fatal_error(out.str());
    313326        }
    314         Value * exitValue = f->second;
    315         assert (phi->getType() == exitValue->getType());
    316         phi->addIncoming(exitValue, whileExitBlock);
    317         f->second = phi;
     327
     328        Value * const outgoingValue = f->second;
     329
     330        if (LLVM_UNLIKELY(incomingPhi->getType() != outgoingValue->getType())) {
     331            std::string tmp;
     332            raw_string_ostream out(tmp);
     333            out << "PHINode creation error: incoming type of ";
     334            var->print(out);
     335            out << " (";
     336            incomingPhi->getType()->print(out);
     337            out << ") differs from the outgoing type (";
     338            outgoingValue->getType()->print(out);
     339            out << ") within ";
     340            whileStatement->print(out);
     341            llvm::report_fatal_error(out.str());
     342        }
     343
     344        incomingPhi->addIncoming(outgoingValue, whileExitBlock);
     345        f->second = incomingPhi;
    318346    }
    319347
     
    351379
    352380            if (LLVM_UNLIKELY(storeInstRequired || isa<Extract>(expr))) {
    353                 const auto f = mMarkerMap.find(expr);
    354                 if (LLVM_UNLIKELY(f == mMarkerMap.end())) {
     381                const auto f = mMarker.find(expr);
     382                if (LLVM_UNLIKELY(f == mMarker.end())) {
    355383                    std::string tmp;
    356384                    raw_string_ostream out(tmp);
     
    362390                }
    363391                Value * const ptr = f->second;
    364 
    365                 assert (&(value->getContext()) == &(ptr->getContext()));
    366 
    367                 if (isa<Count>(cast<Assign>(stmt)->getValue())) {
    368                     Value * count = iBuilder->CreateLoad(ptr);
    369                     value = iBuilder->CreateTruncOrBitCast(value, count->getType());
    370                     value = iBuilder->CreateAdd(value, count);
    371                 }
    372 
    373                 const Type * const type = value->getType();
    374                 if (isa<VectorType>(type) || isa<IntegerType>(type)) {
    375                     const auto bitWidth = isa<VectorType>(type)
    376                             ? cast<VectorType>(type)->getBitWidth()
    377                             : cast<IntegerType>(type)->getBitWidth();
    378                     iBuilder->CreateAlignedStore(value, ptr, bitWidth / 8);
    379                 } else {
    380                     iBuilder->CreateStore(value, ptr);
    381                 }
     392                iBuilder->CreateAlignedStore(value, ptr, getAlignment(value));
     393                value = ptr;
    382394            }
    383395
     
    385397            Value * array = compileExpression(extract->getArray(), false);
    386398            Value * index = compileExpression(extract->getIndex());
    387             value = iBuilder->CreateGEP(array, {ConstantInt::getNullValue(index->getType()), index}, getName(stmt));
     399            value = iBuilder->CreateGEP(array, {ConstantInt::getNullValue(index->getType()), index}, stmt->getName());
    388400        } else if (isa<And>(stmt)) {
    389401            value = compileExpression(stmt->getOperand(0));
     
    433445            Value * const to_count = compileExpression(c->getExpr());
    434446            const unsigned counterSize = iBuilder->getSizeTy()->getBitWidth();
     447            const auto f = mAccumulator.find(c);
     448            if (LLVM_UNLIKELY(f == mAccumulator.end())) {
     449                llvm::report_fatal_error("Unknown accumulator: " + c->getName().str());
     450            }
     451            Value * ptr = mKernel->getScalarFieldPtr(mSelf, f->second);
     452            Value * count = iBuilder->CreateAlignedLoad(ptr, getPointerElementAlignment(ptr));
    435453            Value * const partial = iBuilder->simd_popcount(counterSize, to_count);
    436454            if (LLVM_UNLIKELY(counterSize <= 1)) {
     
    444462                }
    445463            }
     464            value = iBuilder->CreateAdd(value, count);
     465            iBuilder->CreateStore(value, ptr);
     466
    446467        } else if (const Lookahead * l = dyn_cast<Lookahead>(stmt)) {
    447468            PabloAST * const var = l->getExpr();
     
    460481            const unsigned bit_shift = (l->getAmount() % iBuilder->getBitBlockWidth());
    461482            const unsigned block_shift = (l->getAmount() / iBuilder->getBitBlockWidth());
    462             std::string inputName = var->getName()->to_string();;
     483            std::string inputName = cast<Var>(var)->getName().str();
    463484            Value * blockNo = mKernel->getScalarField(mSelf, blockNoScalar);
    464485            Value * lookAhead_blockPtr  = mKernel->getStreamSetPtr(mSelf, inputName, iBuilder->CreateAdd(blockNo, iBuilder->getSize(block_shift)));
     
    491512        }
    492513
    493         mMarkerMap[expr] = value;
     514        mMarker[expr] = value;
    494515        if (DebugOptionIsSet(DumpTrace)) {
    495             assert (expr->getName());
     516            const String & name = isa<Var>(expr) ? cast<Var>(expr)->getName() : cast<Statement>(expr)->getName();
    496517            if (value->getType()->isVectorTy()) {
    497                 iBuilder->CallPrintRegister(expr->getName()->to_string(), value);
     518                iBuilder->CallPrintRegister(name.str(), value);
    498519            } else if (value->getType()->isIntegerTy()) {
    499                 iBuilder->CallPrintInt(expr->getName()->to_string(), value);
     520                iBuilder->CallPrintInt(name.str(), value);
    500521            }
    501522        }
     
    514535        Value * lh = compileExpression(op->getLH());
    515536        Value * rh = compileExpression(op->getRH());
    516         assert (lh->getType() == rh->getType());
     537        if (LLVM_UNLIKELY(lh->getType() != rh->getType())) {
     538            std::string tmp;
     539            raw_string_ostream out(tmp);
     540            out << "Operator creation error: left hand type of ";
     541            expr->print(out);
     542            out << " (";
     543            lh->getType()->print(out);
     544            out << ") differs from right hand type (";
     545            rh->getType()->print(out);
     546            out << ")";
     547            llvm::report_fatal_error(out.str());
     548        }
    517549        switch (op->getClassTypeId()) {
    518550            case TypeId::Add:
     
    532564            case TypeId::NotEquals:
    533565                return iBuilder->CreateICmpNE(lh, rh);
    534             default:
    535                 break;
     566            default: break;
    536567        }
    537568        std::string tmp;
     
    541572        llvm::report_fatal_error(out.str());
    542573    }
    543     const auto f = mMarkerMap.find(expr);
    544     if (LLVM_UNLIKELY(f == mMarkerMap.end())) {
     574    const auto f = mMarker.find(expr);
     575    if (LLVM_UNLIKELY(f == mMarker.end())) {
    545576        std::string tmp;
    546577        llvm::raw_string_ostream out(tmp);
     578        out << "Compilation error: ";
    547579        expr->print(out);
    548580        out << " was used before definition!";
    549         throw std::runtime_error(out.str());
     581        llvm::report_fatal_error(out.str());
    550582    }
    551583    Value * value = f->second;
    552584    if (LLVM_UNLIKELY(isa<GetElementPtrInst>(value) && ensureLoaded)) {
    553         value = iBuilder->CreateBlockAlignedLoad(value);
     585        value = iBuilder->CreateAlignedLoad(value, getPointerElementAlignment(value));
    554586    }
    555587    return value;
     
    558590PabloCompiler::PabloCompiler(PabloKernel * kernel)
    559591: iBuilder(kernel->getBuilder())
     592, mKernel(kernel)
    560593, mCarryManager(new CarryManager(iBuilder))
    561 , mKernel(kernel)
    562594, mFunction(nullptr) {
    563595
Note: See TracChangeset for help on using the changeset viewer.