source: icGREP/icgrep-devel/icgrep/pablo/pablo_compiler.cpp @ 5202

Last change on this file since 5202 was 5202, checked in by nmedfort, 3 years ago

Initial work on adding types to PabloAST and mutable Var objects.

File size: 22.3 KB
Line 
1/*
2 *  Copyright (c) 2014-16 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 *  icgrep is a trademark of International Characters.
5 */
6
7#include <pablo/pablo_compiler.h>
8#include <pablo/pablo_toolchain.h>
9#include <pablo/codegenstate.h>
10#include <pablo/carry_manager.h>
11#include <pablo/printer_pablos.h>
12#include <pablo/function.h>
13#include <re/re_name.h>
14#include <stdexcept>
15#include <sstream>
16#include <IDISA/idisa_builder.h>
17#include <llvm/IR/Module.h>
18#include <llvm/IR/IRBuilder.h>
19#include <iostream>
20#include <hrtime.h>
21#include <llvm/Support/Debug.h>
22
23namespace pablo {
24
25PabloCompiler::PabloCompiler(PabloKernel * k, PabloFunction * const function)
26: iBuilder(k->getBuilder())
27, mBitBlockType(iBuilder->getBitBlockType())
28, mCarryManager(nullptr)
29, mPabloFunction(function)
30, mKernelBuilder(k)
31, mWhileDepth(0)
32, mIfDepth(0)
33, mFunction(nullptr)
34, mMaxWhileDepth(0) {
35   
36}
37
38Type * PabloCompiler::initializeKernelData() {
39    Examine(mPabloFunction);   
40    mCarryManager = std::unique_ptr<CarryManager>(new CarryManager(iBuilder));
41    Type * carryDataType = mCarryManager->initializeCarryData(mPabloFunction);
42    return carryDataType;
43}
44   
45void PabloCompiler::verifyParameter(const Var * var, const Value * param) {
46    if (LLVM_UNLIKELY(&(param->getContext()) != &(iBuilder->getContext()))) {
47        std::string tmp;
48        raw_string_ostream out(tmp);
49        out << "Cannot compile ";
50        mPabloFunction->print(out);
51        out << ": LLVM Context for ";
52        var->print(out);
53        out << " differs from that of the kernel.";
54        throw std::runtime_error(out.str());
55    }
56}
57
58void PabloCompiler::compile(Function * doBlockFunction) {
59
60    // Make sure that we generate code into the right module.
61    mFunction = doBlockFunction;
62    #ifdef PRINT_TIMING_INFORMATION
63    const timestamp_t pablo_compilation_start = read_cycle_counter();
64    #endif
65
66    //Generate Kernel//
67    iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "entry", doBlockFunction, 0));
68    mSelf = mKernelBuilder->getParameter(doBlockFunction, "self");
69
70    mCarryManager->initializeCodeGen(mKernelBuilder, mSelf);
71     
72    PabloBlock * const entryBlock = mPabloFunction->getEntryBlock(); assert (entryBlock);
73    mMarkerMap.emplace(entryBlock->createZeroes(), iBuilder->allZeroes());
74    mMarkerMap.emplace(entryBlock->createOnes(), iBuilder->allOnes());
75
76    Value * const blockNo = mKernelBuilder->getScalarField(mSelf, blockNoScalar);
77
78    for (unsigned i = 0, j = 0; i < mPabloFunction->getNumOfParameters(); ++i) {
79        Var * var = mPabloFunction->getParameter(i);
80        std::string name = var->getName()->to_string();
81        Value * input = nullptr;
82        if (var->getType()->isSingleValueType()) {
83            input = mKernelBuilder->getScalarFieldPtr(mSelf, name);
84        } else {
85            input = mKernelBuilder->getStreamSetBlockPtr(mSelf, name, blockNo);
86            input = iBuilder->CreateGEP(input, {iBuilder->getInt32(0), iBuilder->getInt32(j++)});
87        }
88        verifyParameter(var, input);
89        mMarkerMap.emplace(var, input);
90    }
91
92    for (unsigned i = 0, j = 0; i < mPabloFunction->getNumOfResults(); ++i) {
93        Var * var = mPabloFunction->getResult(i);
94        std::string name = var->getName()->to_string();
95        Value * output = nullptr;
96        if (var->getType()->isSingleValueType()) {
97            output = mKernelBuilder->getScalarFieldPtr(mSelf, name);
98        } else {
99            output = mKernelBuilder->getStreamSetBlockPtr(mSelf, name, blockNo);
100            output = iBuilder->CreateGEP(output, {iBuilder->getInt32(0), iBuilder->getInt32(j++)});
101        }
102        verifyParameter(var, output);
103        mMarkerMap.emplace(var, output);
104    }
105
106    compileBlock(entryBlock);
107
108    #ifdef PRINT_TIMING_INFORMATION
109    const timestamp_t pablo_compilation_end = read_cycle_counter();
110    std::cerr << "PABLO COMPILATION TIME: " << (pablo_compilation_end - pablo_compilation_start) << std::endl;
111    #endif
112}
113
114inline void PabloCompiler::Examine(const PabloFunction * const function) {
115    mWhileDepth = 0;
116    mIfDepth = 0;
117    mMaxWhileDepth = 0;
118    Examine(function->getEntryBlock());
119}
120
121void PabloCompiler::Examine(const PabloBlock * const block) {
122    for (const Statement * stmt : *block) {
123        if (LLVM_UNLIKELY(isa<Lookahead>(stmt))) {
124            const Lookahead * const la = cast<Lookahead>(stmt);
125            assert (isa<Var>(la->getExpr()));
126            if (LLVM_LIKELY(la->getAmount() > mKernelBuilder->getLookAhead())) {
127                mKernelBuilder->setLookAhead(la->getAmount());
128            }
129        } else {
130            if (LLVM_UNLIKELY(isa<If>(stmt))) {
131                Examine(cast<If>(stmt)->getBody());
132            } else if (LLVM_UNLIKELY(isa<While>(stmt))) {
133                mMaxWhileDepth = std::max(mMaxWhileDepth, ++mWhileDepth);
134                Examine(cast<While>(stmt)->getBody());
135                --mWhileDepth;
136            }
137        }
138    }   
139}
140
141inline void PabloCompiler::compileBlock(const PabloBlock * const block) {
142    for (const Statement * statement : *block) {
143        compileStatement(statement);
144    }
145}
146
147static const llvm::StringRef EmptyString;
148
149inline const llvm::StringRef & getName(const PabloAST * expr) {
150    if (expr->getName()) {
151        return expr->getName()->value();
152    }
153    return EmptyString;
154}
155
156void PabloCompiler::compileIf(const If * const ifStatement) {
157    //
158    //  The If-ElseZero stmt:
159    //  if <predicate:expr> then <body:stmt>* elsezero <defined:var>* endif
160    //  If the value of the predicate is nonzero, then determine the values of variables
161    //  <var>* by executing the given statements.  Otherwise, the value of the
162    //  variables are all zero.  Requirements: (a) no variable that is defined within
163    //  the body of the if may be accessed outside unless it is explicitly
164    //  listed in the variable list, (b) every variable in the defined list receives
165    //  a value within the body, and (c) the logical consequence of executing
166    //  the statements in the event that the predicate is zero is that the
167    //  values of all defined variables indeed work out to be 0.
168    //
169    //  Simple Implementation with Phi nodes:  a phi node in the if exit block
170    //  is inserted for each variable in the defined variable list.  It receives
171    //  a zero value from the ifentry block and the defined value from the if
172    //  body.
173    //
174
175    Module * const mod = iBuilder->getModule();
176    BasicBlock * const ifEntryBlock = iBuilder->GetInsertBlock();
177    BasicBlock * const ifBodyBlock = BasicBlock::Create(mod->getContext(), "if.body", mFunction, 0);
178    BasicBlock * const ifEndBlock = BasicBlock::Create(mod->getContext(), "if.end", mFunction, 0);
179   
180    std::vector<std::pair<const Var *, Value *>> incoming;
181
182    for (const Var * var : ifStatement->getEscaped()) {
183        auto f = mMarkerMap.find(var);
184        if (LLVM_UNLIKELY(f == mMarkerMap.end())) {
185            std::string tmp;
186            raw_string_ostream out(tmp);
187            PabloPrinter::print(var, out);
188            out << " is uninitialized prior to entering ";
189            PabloPrinter::print(ifStatement, out);
190            llvm::report_fatal_error(out.str());
191        }
192        incoming.emplace_back(var, f->second);
193    }
194
195    PabloBlock * ifBody = ifStatement->getBody();
196   
197    Value * const condition = compileExpression(ifStatement->getCondition());
198   
199    mCarryManager->enterScope(ifBody);
200    iBuilder->CreateCondBr(mCarryManager->generateSummaryTest(condition), ifBodyBlock, ifEndBlock);
201   
202    // Entry processing is complete, now handle the body of the if.
203    iBuilder->SetInsertPoint(ifBodyBlock);
204   
205    compileBlock(ifBody);
206
207    BasicBlock * ifExitBlock = iBuilder->GetInsertBlock();
208
209    if (mCarryManager->hasCarries()) {
210        mCarryManager->storeCarryOutSummary();
211    }
212    mCarryManager->addOuterSummaryToNestedSummary();
213
214    iBuilder->CreateBr(ifEndBlock);
215    //End Block
216    iBuilder->SetInsertPoint(ifEndBlock);
217    for (const auto i : incoming) {
218        const Var * var; Value * value;
219        std::tie(var, value) = i;
220
221        auto f = mMarkerMap.find(var);
222        if (LLVM_UNLIKELY(f == mMarkerMap.end() || f->second == value)) {
223            std::string tmp;
224            raw_string_ostream out(tmp);
225            PabloPrinter::print(var, out);
226            out << " was not assigned a value.";
227            llvm::report_fatal_error(out.str());
228        }
229
230        PHINode * phi = iBuilder->CreatePHI(mBitBlockType, 2, getName(var));
231        phi->addIncoming(value, ifEntryBlock);
232        phi->addIncoming(f->second, ifExitBlock);
233        f->second = phi;
234
235        assert (mMarkerMap[var] == phi);
236    }
237    // Create the phi Node for the summary variable, if needed.
238    mCarryManager->buildCarryDataPhisAfterIfBody(ifEntryBlock, ifExitBlock);
239    mCarryManager->leaveScope();
240}
241
242void PabloCompiler::compileWhile(const While * const whileStatement) {
243
244    PabloBlock * const whileBody = whileStatement->getBody();
245   
246    BasicBlock * whileEntryBlock = iBuilder->GetInsertBlock();
247
248    Module * const mod = iBuilder->getModule();
249    BasicBlock * whileBodyBlock = BasicBlock::Create(mod->getContext(), "while.body", mFunction, 0);
250    BasicBlock * whileEndBlock = BasicBlock::Create(mod->getContext(), "while.end", mFunction, 0);
251
252    mCarryManager->enterScope(whileBody);
253    mCarryManager->ensureCarriesLoadedRecursive();
254
255#ifdef ENABLE_BOUNDED_WHILE
256    PHINode * bound_phi = nullptr;  // Needed for bounded while loops.
257#endif
258    // On entry to the while structure, proceed to execute the first iteration
259    // of the loop body unconditionally.   The while condition is tested at the end of
260    // the loop.
261
262    iBuilder->CreateBr(whileBodyBlock);
263    iBuilder->SetInsertPoint(whileBodyBlock);
264
265    //
266    // There are 3 sets of Phi nodes for the while loop.
267    // (1) Carry-ins: (a) incoming carry data first iterations, (b) zero thereafter
268    // (2) Carry-out accumulators: (a) zero first iteration, (b) |= carry-out of each iteration
269    // (3) Next nodes: (a) values set up before loop, (b) modified values calculated in loop.
270#ifdef ENABLE_BOUNDED_WHILE
271    // (4) The loop bound, if any.
272#endif
273
274    mCarryManager->initializeWhileEntryCarryDataPhis(whileEntryBlock);
275
276    std::vector<std::pair<const Var *, PHINode *>> variants;
277
278    // for any Next nodes in the loop body, initialize to (a) pre-loop value.
279    for (const auto var : whileStatement->getEscaped()) {
280        PHINode * phi = iBuilder->CreatePHI(mBitBlockType, 2, getName(var));
281        auto f = mMarkerMap.find(var);
282        if (LLVM_UNLIKELY(f == mMarkerMap.end())) {
283            std::string tmp;
284            raw_string_ostream out(tmp);
285            PabloPrinter::print(var, out);
286            out << " was not assigned a value.";
287            llvm::report_fatal_error(out.str());
288        }
289        phi->addIncoming(f->second, whileEntryBlock);
290        f->second = phi;
291        assert(mMarkerMap[var] == phi);
292        variants.emplace_back(var, phi);
293    }
294#ifdef ENABLE_BOUNDED_WHILE
295    if (whileStatement->getBound()) {
296        bound_phi = iBuilder->CreatePHI(iBuilder->getSizeTy(), 2, "while_bound");
297        bound_phi->addIncoming(ConstantInt::get(iBuilder->getSizeTy(), whileStatement->getBound()), whileEntryBlock);
298    }
299#endif
300    //
301    // Now compile the loop body proper.  Carry-out accumulated values
302    // and iterated values of Next nodes will be computed.
303    ++mWhileDepth;
304    compileBlock(whileBody);
305
306    // After the whileBody has been compiled, we may be in a different basic block.
307    BasicBlock * whileExitBlock = iBuilder->GetInsertBlock();
308
309    if (mCarryManager->hasCarries()) {
310        mCarryManager->storeCarryOutSummary();
311    }
312    mCarryManager->finalizeWhileBlockCarryDataPhis(whileExitBlock);
313
314    // Terminate the while loop body with a conditional branch back.
315    Value * cond_expr = iBuilder->bitblock_any(compileExpression(whileStatement->getCondition()));
316#ifdef ENABLE_BOUNDED_WHILE
317    if (whileStatement->getBound()) {
318        Value * new_bound = iBuilder->CreateSub(bound_phi, ConstantInt::get(iBuilder->getSizeTy(), 1));
319        bound_phi->addIncoming(new_bound, whileExitBlock);
320        cond_expr = iBuilder->CreateAnd(cond_expr, iBuilder->CreateICmpUGT(new_bound, ConstantInt::getNullValue(iBuilder->getSizeTy())));
321    }
322#endif   
323    iBuilder->CreateCondBr(cond_expr, whileBodyBlock, whileEndBlock);
324
325    // and for any variant nodes in the loop body
326    for (const auto variant : variants) {
327        const Var * var; PHINode * phi;
328        std::tie(var, phi) = variant;
329        const auto f = mMarkerMap.find(var);
330        if (LLVM_UNLIKELY(f == mMarkerMap.end() || f->second == phi)) {
331            std::string tmp;
332            raw_string_ostream out(tmp);
333            PabloPrinter::print(var, out);
334            out << " was not assigned a value.";
335            llvm::report_fatal_error(out.str());
336        }
337        phi->addIncoming(f->second, whileExitBlock);
338        f->second = phi;
339    }
340
341    iBuilder->SetInsertPoint(whileEndBlock);
342    --mWhileDepth;
343
344    mCarryManager->ensureCarriesStoredRecursive();
345    mCarryManager->leaveScope();
346}
347
348void PabloCompiler::compileStatement(const Statement * stmt) {
349
350    if (LLVM_UNLIKELY(isa<If>(stmt))) {
351        compileIf(cast<If>(stmt));
352    } else if (LLVM_UNLIKELY(isa<While>(stmt))) {
353        compileWhile(cast<While>(stmt));
354    } else {
355        const PabloAST * expr = stmt;
356        Value * value = nullptr;
357        if (LLVM_UNLIKELY(isa<Assign>(stmt))) {
358
359            expr = cast<Assign>(stmt)->getVariable();
360            value = compileExpression(cast<Assign>(stmt)->getValue());
361
362            bool storeInstRequired = false;
363            if (LLVM_LIKELY(isa<Var>(expr))) {
364                for (unsigned i = 0; i < mPabloFunction->getNumOfResults(); ++i) {
365                    if (expr == mPabloFunction->getResult(i)) {
366                        storeInstRequired = true;
367                        break;
368                    }
369                }
370            }
371
372            if (LLVM_UNLIKELY(storeInstRequired || isa<Extract>(expr))) {
373
374                const auto f = mMarkerMap.find(expr);
375                if (LLVM_UNLIKELY(f == mMarkerMap.end())) {
376                    std::string tmp;
377                    raw_string_ostream out(tmp);
378                    PabloPrinter::print(expr, out);
379                    out << " was not defined prior to ";
380                    PabloPrinter::print(stmt, out);
381                    throw std::runtime_error(out.str());
382                }
383                Value * const ptr = f->second;
384
385                assert (&(value->getContext()) == &(ptr->getContext()));
386
387                if (isa<Count>(cast<Assign>(stmt)->getValue())) {
388                    Value * count = iBuilder->CreateLoad(ptr);
389                    Value * accum = iBuilder->CreateAdd(value, count);
390                    iBuilder->CreateStore(accum, ptr);
391                } else {
392                    iBuilder->CreateBlockAlignedStore(value, ptr);
393                }
394            }
395
396        } else if (const Extract * extract = dyn_cast<Extract>(stmt)) {
397            Value * array = compileExpression(extract->getArray(), false);
398            Value * index = compileExpression(extract->getIndex());
399            value = iBuilder->CreateGEP(array, index, getName(stmt));
400        } else if (const And * pablo_and = dyn_cast<And>(stmt)) {
401            value = iBuilder->simd_and(compileExpression(pablo_and->getOperand(0)), compileExpression(pablo_and->getOperand(1)));
402        } else if (const Or * pablo_or = dyn_cast<Or>(stmt)) {
403            value = iBuilder->simd_or(compileExpression(pablo_or->getOperand(0)), compileExpression(pablo_or->getOperand(1)));
404        } else if (const Xor * pablo_xor = dyn_cast<Xor>(stmt)) {
405            value = iBuilder->simd_xor(compileExpression(pablo_xor->getOperand(0)), compileExpression(pablo_xor->getOperand(1)));
406        } else if (const Sel * sel = dyn_cast<Sel>(stmt)) {
407            Value* ifMask = compileExpression(sel->getCondition());
408            Value* ifTrue = iBuilder->simd_and(ifMask, compileExpression(sel->getTrueExpr()));
409            Value* ifFalse = iBuilder->simd_and(iBuilder->simd_not(ifMask), compileExpression(sel->getFalseExpr()));
410            value = iBuilder->simd_or(ifTrue, ifFalse);
411        } else if (const Not * pablo_not = dyn_cast<Not>(stmt)) {
412            value = iBuilder->simd_not(compileExpression(pablo_not->getExpr()));
413        } else if (const Advance * adv = dyn_cast<Advance>(stmt)) {
414            Value * const strm_value = compileExpression(adv->getExpr());
415            value = mCarryManager->advanceCarryInCarryOut(adv->getLocalIndex(), adv->getAmount(), strm_value);
416        } else if (const MatchStar * mstar = dyn_cast<MatchStar>(stmt)) {
417            Value * const marker = compileExpression(mstar->getMarker());
418            Value * const cc = compileExpression(mstar->getCharClass());
419            Value * const marker_and_cc = iBuilder->simd_and(marker, cc);
420            Value * const sum = mCarryManager->addCarryInCarryOut(mstar->getLocalCarryIndex(), marker_and_cc, cc);
421            value = iBuilder->simd_or(iBuilder->simd_xor(sum, cc), marker);
422        } else if (const ScanThru * sthru = dyn_cast<ScanThru>(stmt)) {
423            Value * const  marker_expr = compileExpression(sthru->getScanFrom());
424            Value * const  cc_expr = compileExpression(sthru->getScanThru());
425            Value * const  sum = mCarryManager->addCarryInCarryOut(sthru->getLocalCarryIndex(), marker_expr, cc_expr);
426            value = iBuilder->simd_and(sum, iBuilder->simd_not(cc_expr));
427        } else if (const InFile * e = dyn_cast<InFile>(stmt)) {
428            Value * EOFmask = mKernelBuilder->getScalarField(mSelf, "EOFmask");
429            value = iBuilder->simd_xor(compileExpression(e->getExpr()), EOFmask);
430        } else if (const AtEOF * e = dyn_cast<AtEOF>(stmt)) {
431            Value * EOFbit = mKernelBuilder->getScalarField(mSelf, "EOFbit");
432            value = iBuilder->simd_and(compileExpression(e->getExpr()), EOFbit);
433        } else if (const Count * c = dyn_cast<Count>(stmt)) {
434            Value * const to_count = compileExpression(c->getExpr());
435            const unsigned counterSize = 64;
436            Value * fieldCounts = iBuilder->simd_popcount(counterSize, to_count);
437            value = iBuilder->mvmd_extract(counterSize, fieldCounts, 0);
438            for (unsigned i = 1; i < (iBuilder->getBitBlockWidth() / counterSize); ++i) {
439                Value * temp = iBuilder->mvmd_extract(counterSize, fieldCounts, i);
440                value = iBuilder->CreateAdd(value, temp);
441            }
442        } else if (const Lookahead * l = dyn_cast<Lookahead>(stmt)) {
443            PabloAST * const var = l->getExpr();
444            if (LLVM_UNLIKELY(!isa<Var>(var))) {
445                throw std::runtime_error("Lookahead operations may only be applied to input streams");
446            }
447            unsigned index = 0;
448            for (; index < mPabloFunction->getNumOfParameters(); ++index) {
449                if (mPabloFunction->getParameter(index) == var) {
450                    break;
451                }
452            }
453            if (LLVM_UNLIKELY(index >= mPabloFunction->getNumOfParameters())) {
454                throw std::runtime_error("Lookahead has an illegal Var operand");
455            }
456            const unsigned bit_shift = (l->getAmount() % iBuilder->getBitBlockWidth());
457            const unsigned block_shift = (l->getAmount() / iBuilder->getBitBlockWidth());
458            std::string inputName = var->getName()->to_string();;
459            Value * blockNo = mKernelBuilder->getScalarField(mSelf, blockNoScalar);
460            Value * lookAhead_blockPtr  = mKernelBuilder->getStreamSetBlockPtr(mSelf, inputName, iBuilder->CreateAdd(blockNo, ConstantInt::get(iBuilder->getSizeTy(), block_shift)));
461            Value * lookAhead_inputPtr = iBuilder->CreateGEP(lookAhead_blockPtr, {iBuilder->getInt32(0), iBuilder->getInt32(index)});
462            Value * lookAhead = iBuilder->CreateBlockAlignedLoad(lookAhead_inputPtr);
463            if (bit_shift == 0) {  // Simple case with no intra-block shifting.
464                value = lookAhead;
465            } else { // Need to form shift result from two adjacent blocks.
466                Value * lookAhead_blockPtr1  = mKernelBuilder->getStreamSetBlockPtr(mSelf, inputName, iBuilder->CreateAdd(blockNo, ConstantInt::get(iBuilder->getSizeTy(), block_shift + 1)));
467                Value * lookAhead_inputPtr1 = iBuilder->CreateGEP(lookAhead_blockPtr1, {iBuilder->getInt32(0), iBuilder->getInt32(index)});
468                Value * lookAhead1 = iBuilder->CreateBlockAlignedLoad(lookAhead_inputPtr1);
469                if (LLVM_UNLIKELY((bit_shift % 8) == 0)) { // Use a single whole-byte shift, if possible.
470                    value = iBuilder->mvmd_dslli(8, lookAhead1, lookAhead, (bit_shift / 8));
471                } else {
472                    Type  * const streamType = iBuilder->getIntNTy(iBuilder->getBitBlockWidth());
473                    Value * b1 = iBuilder->CreateBitCast(lookAhead1, streamType);
474                    Value * b0 = iBuilder->CreateBitCast(lookAhead, streamType);
475                    Value * result = iBuilder->CreateOr(iBuilder->CreateShl(b1, iBuilder->getBitBlockWidth() - bit_shift), iBuilder->CreateLShr(b0, bit_shift));
476                    value = iBuilder->CreateBitCast(result, mBitBlockType);
477                }
478            }
479
480        } else {
481            std::string tmp;
482            llvm::raw_string_ostream msg(tmp);
483            msg << "Internal error: ";
484            PabloPrinter::print(stmt, msg);
485            msg << " is not a recognized statement in the Pablo compiler.";
486            throw std::runtime_error(msg.str());
487        }
488
489        mMarkerMap[expr] = value;
490
491        if (DebugOptionIsSet(DumpTrace)) {
492            iBuilder->CallPrintRegister(stmt->getName()->to_string(), value);
493        }
494    }
495}
496
497Value * PabloCompiler::compileExpression(const PabloAST * expr, const bool ensureLoaded) const {
498    if (LLVM_UNLIKELY(isa<Ones>(expr))) {
499        return iBuilder->allOnes();
500    } else if (LLVM_UNLIKELY(isa<Zeroes>(expr))) {
501        return iBuilder->allZeroes();
502    } else if (LLVM_UNLIKELY(isa<Integer>(expr))) {
503        return iBuilder->getInt64(cast<Integer>(expr)->value());
504    }
505    const auto f = mMarkerMap.find(expr);
506    if (LLVM_UNLIKELY(f == mMarkerMap.end())) {
507        std::string tmp;
508        llvm::raw_string_ostream out(tmp);
509        PabloPrinter::print(expr, out);
510        out << " was used before definition!";
511        throw std::runtime_error(out.str());
512    }
513    Value * value = f->second;
514    if (LLVM_UNLIKELY(isa<GetElementPtrInst>(value) && ensureLoaded)) {
515        value = iBuilder->CreateBlockAlignedLoad(value);
516    }
517    return value;
518}
519
520}
Note: See TracBrowser for help on using the repository browser.