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

Last change on this file since 5117 was 5117, checked in by cameron, 3 years ago

bitblock_advance

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