source: icGREP/icgrep-devel/icgrep/pablo/carry_manager.cpp @ 5160

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

Initial work for incorporating Types into Pablo AST.

File size: 24.9 KB
Line 
1/*
2 *  Copyright (c) 2015 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 <stdexcept>
8#include <pablo/carry_data.h>
9#include <pablo/codegenstate.h>
10#include <pablo/carry_manager.h>
11#include <pablo/pabloAST.h>
12#include <llvm/Support/CommandLine.h>
13#include <llvm/IR/BasicBlock.h>
14#include <llvm/IR/CallingConv.h>
15#include <llvm/IR/Function.h>
16#include <iostream>
17
18
19namespace pablo {
20
21/** ------------------------------------------------------------------------------------------------------------- *
22 * @brief initializeCarryData
23 ** ------------------------------------------------------------------------------------------------------------- */
24Type * CarryManager::initializeCarryData(PabloFunction * const function) {
25    mRootScope = function->getEntryBlock();
26    mCarryInfoVector.resize(mRootScope->enumerateScopes(0) + 1);
27    mCarryPackType = mBitBlockType;
28    const unsigned totalCarryDataSize = enumerate(mRootScope, 0, 0);
29
30    mCarryPackPtr.resize(totalCarryDataSize + 1, nullptr);
31    mCarryInPack.resize(totalCarryDataSize + 1, nullptr);
32    mCarryOutPack.resize(totalCarryDataSize + 1, nullptr);
33
34    mTotalCarryDataBitBlocks = totalCarryDataSize;
35    ArrayType* cdArrayTy = ArrayType::get(mBitBlockType, mTotalCarryDataBitBlocks);
36    return cdArrayTy;
37}
38
39/** ------------------------------------------------------------------------------------------------------------- *
40 * @brief initializeCodeGen
41 ** ------------------------------------------------------------------------------------------------------------- */
42void CarryManager::initializeCodeGen(PabloKernel * const kBuilder, Value * selfPtr) {
43    mKernelBuilder = kBuilder;
44    mSelf = selfPtr;
45   
46    Value * cdArrayPtr = iBuilder->CreateGEP(mSelf, {ConstantInt::get(iBuilder->getSizeTy(), 0), mKernelBuilder->getScalarIndex("carries")});
47//#ifndef NDEBUG
48//    iBuilder->CallPrintInt("cdArrayPtr", iBuilder->CreatePtrToInt(cdArrayPtr, iBuilder->getSizeTy()));
49//#endif
50    mCarryPackBasePtr = iBuilder->CreateBitCast(cdArrayPtr, PointerType::get(mCarryPackType, 0));
51    mCarryBitBlockPtr = iBuilder->CreateBitCast(cdArrayPtr, PointerType::get(mBitBlockType, 0));
52    mCurrentScope = mRootScope;
53    mCurrentFrameIndex = 0;
54    assert(mCarryInfoVector.size() > 0);
55    mCarryInfo = mCarryInfoVector[0];
56    assert(summaryPack() < mCarryOutPack.size());
57    mCarryOutPack[summaryPack()] = Constant::getNullValue(mCarryPackType);
58    assert (mCarrySummary.empty());
59}
60
61/** ------------------------------------------------------------------------------------------------------------- *
62 * @brief enterScope
63 ** ------------------------------------------------------------------------------------------------------------- */
64void CarryManager::enterScope(PabloBlock * const scope) {
65    assert(summaryPack() < mCarryOutPack.size());
66    Value * summaryCarry = mCarryOutPack[summaryPack()];
67    mCarrySummary.push_back(summaryCarry);
68    mCurrentScope = scope;
69    mCarryInfo = mCarryInfoVector[scope->getScopeIndex()];
70    mCurrentFrameIndex += mCarryInfo->getFrameIndex();
71    assert(summaryPack() < mCarryOutPack.size());
72    mCarryOutPack[summaryPack()] = Constant::getNullValue(mCarryPackType);
73}
74
75/** ------------------------------------------------------------------------------------------------------------- *
76 * @brief leaveScope
77 ** ------------------------------------------------------------------------------------------------------------- */
78void CarryManager::leaveScope() {
79    assert(summaryPack() < mCarryOutPack.size());
80    Value * summaryCarry = mCarryOutPack[summaryPack()];
81    assert (mCurrentScope != mRootScope);
82    mCurrentFrameIndex -= mCarryInfo->getFrameIndex();
83    mCurrentScope = mCurrentScope->getPredecessor ();
84    mCarryInfo = mCarryInfoVector[mCurrentScope->getScopeIndex()];
85    assert(summaryPack() < mCarryOutPack.size());
86    mCarryOutPack[summaryPack()] = summaryCarry;
87    mCarrySummary.pop_back();
88}
89
90/** ------------------------------------------------------------------------------------------------------------- *
91 * @brief addCarryInCarryOut
92 ** ------------------------------------------------------------------------------------------------------------- */
93Value * CarryManager::addCarryInCarryOut(const unsigned localIndex, Value * const e1, Value * const e2) {
94    std::pair<Value *, Value *> fullAdd = iBuilder->bitblock_add_with_carry(e1, e2, getCarryIn(localIndex));
95    setCarryOut(localIndex, std::get<0>(fullAdd));
96    return std::get<1>(fullAdd);
97}
98
99/** ------------------------------------------------------------------------------------------------------------- *
100 * @brief advanceCarryInCarryOut
101 ** ------------------------------------------------------------------------------------------------------------- */
102Value * CarryManager::advanceCarryInCarryOut(const unsigned localIndex, const unsigned shiftAmount, Value * const value) {
103    if (LLVM_LIKELY(shiftAmount == 1)) {
104        return shortAdvanceCarryInCarryOut(unitAdvancePosition(localIndex), shiftAmount, value);
105    } else if (shiftAmount < LongAdvanceBase) {
106        return shortAdvanceCarryInCarryOut(shortAdvancePosition(localIndex), shiftAmount, value);
107    } else {
108        return longAdvanceCarryInCarryOut(longAdvancePosition(localIndex), shiftAmount, value);
109    }
110}
111
112/** ------------------------------------------------------------------------------------------------------------- *
113 * @brief shortAdvanceCarryInCarryOut
114 ** ------------------------------------------------------------------------------------------------------------- */
115Value * CarryManager::shortAdvanceCarryInCarryOut(const unsigned index, const unsigned shiftAmount, Value * const value) {
116    Value * const carryIn = getCarryPack(index);
117    assert (index < mCarryOutPack.size());
118    std::pair<Value *, Value *> adv = iBuilder->bitblock_advance(value, carryIn, shiftAmount);
119    mCarryOutPack[index] = std::get<0>(adv);
120    if (mCarryInfo->getWhileDepth() == 0) {
121        storeCarryOut(index);
122    }
123    if (LLVM_LIKELY(hasSummary())) {
124        addToSummary(value);
125    }
126    return std::get<1>(adv);
127}
128
129/** ------------------------------------------------------------------------------------------------------------- *
130 * @brief longAdvanceCarryInCarryOut
131 ** ------------------------------------------------------------------------------------------------------------- */
132Value * CarryManager::longAdvanceCarryInCarryOut(const unsigned index, const unsigned shiftAmount, Value * const value) {
133    Value * advBaseIndex = ConstantInt::get(iBuilder->getSizeTy(), index);
134    if (shiftAmount <= mBitBlockWidth) {
135        // special case using a single buffer entry and the carry_out value.
136        Value * advanceDataPtr = iBuilder->CreateGEP(mCarryBitBlockPtr, advBaseIndex);
137        Value * carry_block0 = iBuilder->CreateBlockAlignedLoad(advanceDataPtr);
138        iBuilder->CreateBlockAlignedStore(value, advanceDataPtr);
139        /* Very special case - no combine */
140        if (shiftAmount == mBitBlockWidth) {
141            return carry_block0;
142        }
143        Value* block0_shr = iBuilder->CreateLShr(iBuilder->CreateBitCast(carry_block0, iBuilder->getIntNTy(mBitBlockWidth)), mBitBlockWidth - shiftAmount);
144        Value* block1_shl = iBuilder->CreateShl(iBuilder->CreateBitCast(value, iBuilder->getIntNTy(mBitBlockWidth)), shiftAmount);
145        return iBuilder->CreateBitCast(iBuilder->CreateOr(block1_shl, block0_shr), mBitBlockType);
146    }
147    // We need a buffer of at least two elements for storing the advance data.
148    const unsigned block_shift = shiftAmount % mBitBlockWidth;
149    const unsigned advanceEntries = mCarryInfo->longAdvanceEntries(shiftAmount);
150    const unsigned bufsize = mCarryInfo->longAdvanceBufferSize(shiftAmount);
151    Value * indexMask = ConstantInt::get(iBuilder->getSizeTy(), bufsize - 1);  // A mask to implement circular buffer indexing
152    Value * blockIndex = mKernelBuilder->getScalarField(mSelf, blockNoScalar);
153    Value * loadIndex0 = iBuilder->CreateAdd(iBuilder->CreateAnd(iBuilder->CreateSub(blockIndex, ConstantInt::get(iBuilder->getSizeTy(), advanceEntries)), indexMask), advBaseIndex);
154    Value * storeIndex = iBuilder->CreateAdd(iBuilder->CreateAnd(blockIndex, indexMask), advBaseIndex);
155    Value * carry_block0 = iBuilder->CreateBlockAlignedLoad(iBuilder->CreateGEP(mCarryBitBlockPtr, loadIndex0));
156    // If the long advance is an exact multiple of mBITBLOCK_WIDTH, we simply return the oldest
157    // block in the long advance carry data area. 
158    if (block_shift == 0) {
159        iBuilder->CreateBlockAlignedStore(value, iBuilder->CreateGEP(mCarryBitBlockPtr, storeIndex));
160        return carry_block0;
161    }
162    // Otherwise we need to combine data from the two oldest blocks.
163    Value * loadIndex1 = iBuilder->CreateAdd(iBuilder->CreateAnd(iBuilder->CreateSub(blockIndex, ConstantInt::get(iBuilder->getSizeTy(), advanceEntries-1)), indexMask), advBaseIndex);
164    Value * carry_block1 = iBuilder->CreateBlockAlignedLoad(iBuilder->CreateGEP(mCarryBitBlockPtr, loadIndex1));
165    Value* block0_shr = iBuilder->CreateLShr(iBuilder->CreateBitCast(carry_block0, iBuilder->getIntNTy(mBitBlockWidth)), mBitBlockWidth - block_shift);
166    Value* block1_shl = iBuilder->CreateShl(iBuilder->CreateBitCast(carry_block1, iBuilder->getIntNTy(mBitBlockWidth)), block_shift);
167    iBuilder->CreateBlockAlignedStore(value, iBuilder->CreateGEP(mCarryBitBlockPtr, storeIndex));
168    return iBuilder->CreateBitCast(iBuilder->CreateOr(block1_shl, block0_shr), mBitBlockType);
169}
170
171/** ------------------------------------------------------------------------------------------------------------- *
172 * @brief generateSummaryTest
173 ** ------------------------------------------------------------------------------------------------------------- */
174Value * CarryManager::generateSummaryTest(Value * condition) {
175    if (mCarryInfo->hasCarries()) {
176        Value * summary_pack = getCarryPack(summaryPack());
177        condition = iBuilder->simd_or(condition, summary_pack);
178    }
179    return iBuilder->bitblock_any(condition);
180}
181
182/** ------------------------------------------------------------------------------------------------------------- *
183 * @brief storeCarryOutSummary
184 ** ------------------------------------------------------------------------------------------------------------- */
185void CarryManager::storeCarryOutSummary() {
186    if (LLVM_LIKELY(mCarryInfo->explicitSummaryRequired())) {
187        const unsigned carrySummaryIndex = summaryPack();
188        if (LLVM_UNLIKELY(mCarryInfo->hasLongAdvances())) { // Force if entry
189            assert (carrySummaryIndex < mCarryOutPack.size());
190            mCarryOutPack[carrySummaryIndex] = Constant::getAllOnesValue(mCarryPackType);
191        }
192        storeCarryOut(carrySummaryIndex);
193    }
194}
195
196/** ------------------------------------------------------------------------------------------------------------- *
197 * @brief addOuterSummaryToNestedSummary
198 ** ------------------------------------------------------------------------------------------------------------- */
199void CarryManager::addOuterSummaryToNestedSummary() {
200    if (LLVM_LIKELY(mCarrySummary.size() > 0)) {
201        addToSummary(mCarrySummary.back());
202    }
203}
204
205/** ------------------------------------------------------------------------------------------------------------- *
206 * @brief buildCarryDataPhisAfterIfBody
207 ** ------------------------------------------------------------------------------------------------------------- */
208void CarryManager::buildCarryDataPhisAfterIfBody(BasicBlock * const entry, BasicBlock * const end) {
209    if (mCarryInfo->getWhileDepth() > 0) {
210        // We need to phi out everything for the while carry accumulation process.
211        const unsigned scopeBaseOffset = scopeBasePack();
212        const unsigned scopeCarryPacks = mCarryInfo->getScopeCarryPackCount();
213        for (unsigned i = scopeBaseOffset; i < scopeBaseOffset + scopeCarryPacks; ++i) {
214            assert (i < mCarryOutPack.size());
215            Type * const type = mCarryOutPack[i]->getType();
216            PHINode * phi = iBuilder->CreatePHI(type, 2);
217            phi->addIncoming(Constant::getNullValue(type), entry);
218            phi->addIncoming(mCarryOutPack[i], end);
219            mCarryOutPack[i] = phi;
220        }
221    }
222    if (LLVM_LIKELY(mCarrySummary.size() > 0)) {
223        const unsigned summaryIndex = summaryPack();
224        assert (summaryIndex < mCarryOutPack.size());
225        Value * carrySummary = mCarryOutPack[summaryIndex];
226        if (mCarrySummary.back() != carrySummary) {
227            Value * outerCarrySummary = mCarrySummary.back();
228            Value * nestedCarrySummary = mCarryOutPack[summaryIndex];
229            assert (outerCarrySummary->getType() == nestedCarrySummary->getType());
230            PHINode * const phi = iBuilder->CreatePHI(outerCarrySummary->getType(), 2, "summary");
231            phi->addIncoming(outerCarrySummary, entry);
232            phi->addIncoming(nestedCarrySummary, end);
233            mCarryOutPack[summaryIndex] = phi;
234        }
235    }
236}
237
238/** ------------------------------------------------------------------------------------------------------------- *
239 * @brief initializeWhileEntryCarryDataPhis
240 ** ------------------------------------------------------------------------------------------------------------- */
241void CarryManager::initializeWhileEntryCarryDataPhis(BasicBlock * const end) {
242    const unsigned scopeCarryPacks = mCarryInfo->getScopeCarryPackCount();
243    mCarryOutAccumPhis.resize(scopeCarryPacks);
244    #ifdef SET_WHILE_CARRY_IN_TO_ZERO_AFTER_FIRST_ITERATION
245    const unsigned currentScopeBase = scopeBasePack();
246    mCarryInPhis.resize(scopeCarryPacks);
247    #endif
248    for (unsigned index = 0; index < scopeCarryPacks; ++index) {
249        #ifdef SET_WHILE_CARRY_IN_TO_ZERO_AFTER_FIRST_ITERATION
250        PHINode * phi_in = iBuilder->CreatePHI(mCarryPackType, 2);
251        phi_in->addIncoming(mCarryInPack[currentScopeBase+index], whileEntryBlock);
252        mCarryInPhis[index] = phi_in;
253        #endif
254        PHINode * phi_out = iBuilder->CreatePHI(mCarryPackType, 2);
255        phi_out->addIncoming(Constant::getNullValue(mCarryPackType), end);
256        assert (index < mCarryOutAccumPhis.size());
257        mCarryOutAccumPhis[index] = phi_out;
258    }
259}
260
261/** ------------------------------------------------------------------------------------------------------------- *
262 * @brief finalizeWhileBlockCarryDataPhis
263 ** ------------------------------------------------------------------------------------------------------------- */
264void CarryManager::finalizeWhileBlockCarryDataPhis(BasicBlock * const end) {
265    const unsigned scopeCarryPacks = mCarryInfo->getScopeCarryPackCount();
266    const unsigned currentScopeBase = scopeBasePack();
267    for (unsigned index = 0; index < scopeCarryPacks; ++index) {
268        #ifdef SET_WHILE_CARRY_IN_TO_ZERO_AFTER_FIRST_ITERATION
269        mCarryInPhis[index]->addIncoming(Constant::getNullValue(mCarryPackType), whileBodyFinalBlock);
270        #endif
271        assert (index < mCarryOutAccumPhis.size());
272        PHINode * phi = mCarryOutAccumPhis[index];
273        Value * carryOut = iBuilder->CreateOr(phi, mCarryOutPack[currentScopeBase + index]);
274        phi->addIncoming(carryOut, end);
275        mCarryOutPack[currentScopeBase + index] = carryOut;
276    }
277}
278
279/** ------------------------------------------------------------------------------------------------------------- *
280 * @brief ensureCarriesLoadedRecursive
281 ** ------------------------------------------------------------------------------------------------------------- */
282void CarryManager::ensureCarriesLoadedRecursive() {
283    const unsigned scopeCarryPacks = mCarryInfo->getScopeCarryPackCount();
284    const unsigned currentScopeBase = scopeBasePack();
285    if (mCarryInfo->getWhileDepth() == 1) {
286        for (auto i = currentScopeBase; i < currentScopeBase + scopeCarryPacks; ++i) {
287            getCarryPack(i);
288        }
289    }
290}
291
292/** ------------------------------------------------------------------------------------------------------------- *
293 * @brief ensureCarriesStoredRecursive
294 ** ------------------------------------------------------------------------------------------------------------- */
295void CarryManager::ensureCarriesStoredRecursive() {
296    const unsigned scopeCarryPacks = mCarryInfo->getScopeCarryPackCount();
297    const unsigned currentScopeBase = scopeBasePack();
298    if (mCarryInfo->getWhileDepth() == 1) {
299        for (auto i = currentScopeBase; i < currentScopeBase + scopeCarryPacks; ++i) {
300            storeCarryOut(i);
301        }
302    }
303}
304
305/** ------------------------------------------------------------------------------------------------------------- *
306 * @brief getCarryIn
307 ** ------------------------------------------------------------------------------------------------------------- */
308Value * CarryManager::getCarryIn(const unsigned localIndex) {
309    return getCarryPack(addPosition(localIndex));
310}
311
312/** ------------------------------------------------------------------------------------------------------------- *
313 * @brief setCarryOut
314 ** ------------------------------------------------------------------------------------------------------------- */
315void CarryManager::setCarryOut(const unsigned localIndex, Value * carryOut) {
316    const unsigned index = addPosition(localIndex);
317    assert (index < mCarryOutPack.size());
318    mCarryOutPack[index] = carryOut;
319    if (LLVM_LIKELY(hasSummary())) {
320        addToSummary(carryOut);
321    }
322    if (mCarryInfo->getWhileDepth() == 0) {
323        storeCarryOut(index);
324    }
325}
326
327/** ------------------------------------------------------------------------------------------------------------- *
328 * @brief enumerate
329 ** ------------------------------------------------------------------------------------------------------------- */
330unsigned CarryManager::enumerate(PabloBlock * blk, unsigned ifDepth, unsigned whileDepth) {
331    unsigned idx = blk->getScopeIndex();
332    CarryData * cd = new CarryData(blk, mBitBlockWidth, 1, mBitBlockWidth);
333    mCarryInfoVector[idx] = cd;
334
335    cd->setIfDepth(ifDepth);
336    cd->setWhileDepth(whileDepth);
337    unsigned nestedOffset = cd->nested.frameOffset;
338
339    for (Statement * stmt : *blk) {
340        if (If * ifStatement = dyn_cast<If>(stmt)) {
341            const unsigned ifCarryDataBits = enumerate(ifStatement->getBody(), ifDepth + 1, whileDepth);
342            CarryData * nestedBlockData = mCarryInfoVector[ifStatement->getBody()->getScopeIndex()];
343            if (1 == mBitBlockWidth) {  // PACKING
344                if (cd->roomInFinalPack(nestedOffset) < ifCarryDataBits) {
345                    nestedOffset = alignCeiling(nestedOffset, mBitBlockWidth);
346                }
347            }
348            nestedBlockData->setFramePosition(nestedOffset);
349            nestedOffset += ifCarryDataBits;
350            if (cd->maxNestingDepth <= nestedBlockData->maxNestingDepth) {
351                cd->maxNestingDepth = nestedBlockData->maxNestingDepth + 1;
352            }
353            cd->nested.entries++;
354        } else if (While * whileStatement = dyn_cast<While>(stmt)) {
355            const unsigned whileCarryDataBits = enumerate(whileStatement->getBody(), ifDepth, whileDepth + 1);
356            CarryData * const nestedBlockData = mCarryInfoVector[whileStatement->getBody()->getScopeIndex()];
357            if (1 == mBitBlockWidth) {  // PACKING
358                if (cd->roomInFinalPack(nestedOffset) < whileCarryDataBits) {
359                    nestedOffset = alignCeiling(nestedOffset, mBitBlockWidth);
360                }
361            }
362            nestedBlockData->setFramePosition(nestedOffset);
363            nestedOffset += whileCarryDataBits;
364            if (cd->maxNestingDepth <= nestedBlockData->maxNestingDepth) {
365                cd->maxNestingDepth = nestedBlockData->maxNestingDepth + 1;
366            }
367            cd->nested.entries++;
368        }
369    }
370
371    cd->scopeCarryDataSize = nestedOffset;
372
373    if (cd->explicitSummaryRequired()) {
374        // Need extra space for the summary variable, always the last
375        // entry within an if block.
376        if (1 == mBitBlockWidth) {  // PACKING
377            cd->scopeCarryDataSize = alignCeiling(cd->scopeCarryDataSize, mBitBlockWidth);
378        }
379        cd->summary.frameOffset = cd->scopeCarryDataSize;
380        cd->scopeCarryDataSize += 1;  //  computed summary is a full pack.
381    } else {
382        cd->summary.frameOffset = 0;
383    }
384
385    return cd->scopeCarryDataSize;
386}
387
388/** ------------------------------------------------------------------------------------------------------------- *
389 * @brief addToSummary
390 ** ------------------------------------------------------------------------------------------------------------- */
391void CarryManager::addToSummary(Value * const value) {
392    const unsigned summaryIndex = summaryPack();
393    assert (summaryIndex < mCarryInPack.size());
394    Value * summary = mCarryOutPack[summaryIndex];
395    assert (summary);
396    assert (value);
397    if (LLVM_UNLIKELY(summary == value)) return;  //Nothing to add.
398   
399    Type * summaryTy = summary->getType();
400    Type * valueTy = value->getType();
401    if (LLVM_UNLIKELY(isa<Constant>(value))) {
402        if (LLVM_LIKELY(cast<Constant>(value)->isZeroValue())) return;
403        if (cast<Constant>(value)->isAllOnesValue()) {
404            mCarryOutPack[summaryIndex] = Constant::getAllOnesValue(summaryTy);
405            return;
406        }
407    }
408    Value * v = value;
409    if (valueTy != summaryTy) {
410        // valueTy must be an integer type.
411        unsigned summaryWidth = summaryTy->isIntegerTy() ? summaryTy->getIntegerBitWidth() : cast<VectorType>(summaryTy)->getBitWidth();       
412        if (valueTy->getIntegerBitWidth() != summaryWidth) {
413            v = iBuilder->CreateZExt(v, iBuilder->getIntNTy(summaryWidth));
414        }
415        if (!(summaryTy->isIntegerTy())) {
416            v = iBuilder->CreateBitCast(v, summaryTy);
417        }
418    }
419    if (LLVM_UNLIKELY(isa<Constant>(summary))) {
420        if (LLVM_LIKELY(cast<Constant>(summary)->isZeroValue())) {
421            mCarryOutPack[summaryIndex] = v;
422            return;
423        } else if (cast<Constant>(summary)->isAllOnesValue()) {
424            return;
425        }
426    }
427    mCarryOutPack[summaryIndex] = iBuilder->CreateOr(summary, v, "summary");
428}
429
430/** ------------------------------------------------------------------------------------------------------------- *
431 * @brief getCarryPack
432 ** ------------------------------------------------------------------------------------------------------------- */
433Value * CarryManager::getCarryPack(const unsigned packIndex) {
434    assert (packIndex < mCarryInPack.size());
435    if (mCarryInPack[packIndex] == nullptr) {
436        Value * const packPtr = iBuilder->CreateGEP(mCarryPackBasePtr, ConstantInt::get(iBuilder->getSizeTy(), packIndex));
437        assert (packIndex < mCarryPackPtr.size());
438        mCarryPackPtr[packIndex] = packPtr;
439        mCarryInPack[packIndex] = iBuilder->CreateBlockAlignedLoad(packPtr);
440    }
441    return mCarryInPack[packIndex];
442}
443
444/** ------------------------------------------------------------------------------------------------------------- *
445 * @brief storeCarryOut
446 ** ------------------------------------------------------------------------------------------------------------- */
447void CarryManager::storeCarryOut(const unsigned packIndex) {
448    assert (packIndex < mCarryOutPack.size());
449    assert (mCarryOutPack[packIndex]);
450    assert (packIndex < mCarryPackPtr.size());
451    Value * const ptr = mCarryPackPtr[packIndex];
452    assert (ptr);
453    assert (cast<PointerType>(ptr->getType())->getElementType() == mBitBlockType);
454    Value * const value = iBuilder->CreateBitCast(mCarryOutPack[packIndex], mBitBlockType);
455    iBuilder->CreateBlockAlignedStore(value, ptr);
456}
457
458/* Helper routines */
459
460inline unsigned CarryManager::relativeFrameOffset(const unsigned frameOffset, const unsigned index) const {
461    return mCurrentFrameIndex + frameOffset + index;
462}
463
464inline unsigned CarryManager::addPosition(const unsigned localIndex) const {
465    assert (mCarryInfo);
466    return relativeFrameOffset(mCarryInfo->addWithCarry.frameOffset, localIndex);
467}
468
469inline unsigned CarryManager::unitAdvancePosition(const unsigned localIndex) const {
470    assert (mCarryInfo);
471    return relativeFrameOffset(mCarryInfo->unitAdvance.frameOffset, localIndex);
472}
473
474inline unsigned CarryManager::shortAdvancePosition(const unsigned localIndex) const {
475    assert (mCarryInfo);
476    return relativeFrameOffset(mCarryInfo->shortAdvance.frameOffset, localIndex);
477}
478
479inline unsigned CarryManager::longAdvancePosition(const unsigned localIndex) const {
480    assert (mCarryInfo);
481    return (mCurrentFrameIndex + mCarryInfo->longAdvance.frameOffset) + localIndex;
482}
483
484inline unsigned CarryManager::localBasePack() const {
485    assert (mCarryInfo);
486    return (mCurrentFrameIndex + mCarryInfo->shortAdvance.frameOffset);
487}
488
489inline unsigned CarryManager::scopeBasePack() const {
490    return mCurrentFrameIndex;
491}
492
493inline unsigned CarryManager::summaryPack() const {
494    assert (mCarryInfo);
495    return relativeFrameOffset(mCarryInfo->summary.frameOffset, 0);
496}
497
498inline bool CarryManager::hasSummary() const {
499    assert (mCarryInfo);
500    return mCarryInfo->explicitSummaryRequired() && !(mCarryInfo->hasLongAdvances());
501}
502
503CarryManager::~CarryManager() {
504    for (auto * cd : mCarryInfoVector) {
505        delete cd;
506    }
507}
508
509}
510
Note: See TracBrowser for help on using the repository browser.