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

Last change on this file since 4698 was 4698, checked in by cameron, 4 years ago

Carry manager check in

File size: 21.4 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
8#include <include/simd-lib/bitblock.hpp>
9#include <stdexcept>
10#include <pablo/carry_data.h>
11#include <pablo/codegenstate.h>
12#include <pablo/carry_manager.h>
13#include <pablo/pabloAST.h>
14#include <iostream>
15
16namespace pablo {
17 
18    unsigned doScopeCount(PabloBlock * pb) {
19        unsigned count = 1;
20       
21        for (Statement * stmt : *pb) {
22            if (If * ifStatement = dyn_cast<If>(stmt)) {
23                count += doScopeCount(&ifStatement->getBody());
24            }
25            else if (While * whileStatement = dyn_cast<While>(stmt)) {
26                count += doScopeCount(&whileStatement->getBody());
27            }
28        }
29        return count;
30       
31    }
32
33unsigned CarryManager::initialize(PabloBlock * pb, Value * carryPtr) {
34    mPabloRoot = pb;
35#ifdef PACKING
36    mCarryPackBasePtr = mBuilder->CreateBitCast(carryPtr, Type::getInt64PtrTy(mBuilder->getContext()));
37    mCarryBitBlockPtr = carryPtr;
38#else
39    mCarryPackBasePtr = carryPtr;
40#define mCarryBitBlockPtr mCarryPackBasePtr
41#endif
42    unsigned scopeCount = doScopeCount(pb);
43    mCarryInfoVector.resize(scopeCount);
44   
45    unsigned totalCarryDataBits = enumerate(pb, 0, 0);
46   
47    mTotalCarryDataBitBlocks = (totalCarryDataBits + BLOCK_SIZE - 1)/BLOCK_SIZE; 
48    // Carry Data area will have one extra bit block to store the block number.
49    mBlockNoPtr = mBuilder->CreateBitCast(mBuilder->CreateGEP(carryPtr, mBuilder->getInt64(mTotalCarryDataBitBlocks)), Type::getInt64PtrTy(mBuilder->getContext()));
50    mBlockNo = mBuilder->CreateLoad(mBlockNoPtr);
51    mCarryPackPtr.resize(mTotalCarryDataBitBlocks);
52    mCarryInPack.resize(mTotalCarryDataBitBlocks);
53    mCarryOutPack.resize(mTotalCarryDataBitBlocks);
54    for (auto i = 0; i < mTotalCarryDataBitBlocks; i++) mCarryInPack[i]=nullptr;
55   
56    /*  Set the current scope to PabloRoot */
57    mCurrentScope = mPabloRoot;
58    mCurrentFrameIndex = 0;
59    mCarryInfo = mCarryInfoVector[0];
60
61    return mTotalCarryDataBitBlocks + 1; // One extra element for the block no.
62}
63   
64void CarryManager::generateBlockNoIncrement() {
65    mBuilder->CreateStore(mBuilder->CreateAdd(mBlockNo, mBuilder->getInt64(1)), mBlockNoPtr);
66}
67
68Value * CarryManager::getBlockNoPtr() {
69    return mBlockNoPtr;
70}
71
72
73unsigned CarryManager::enumerate(PabloBlock * blk, unsigned ifDepth, unsigned whileDepth) {
74    llvm::raw_os_ostream cerr(std::cerr);
75    unsigned idx = blk->getScopeIndex();
76    PabloBlockCarryData * cd = new PabloBlockCarryData(blk);
77    mCarryInfoVector[idx] = cd;
78
79    cd->setIfDepth(ifDepth);
80    cd->setWhileDepth(whileDepth);
81    unsigned nestedOffset = cd->nested.frameOffsetinBits;
82 
83    for (Statement * stmt : *blk) {
84        if (If * ifStatement = dyn_cast<If>(stmt)) {
85            const unsigned ifCarryDataBits = enumerate(&ifStatement->getBody(), ifDepth+1, whileDepth);
86            PabloBlockCarryData * nestedBlockData = mCarryInfoVector[ifStatement->getBody().getScopeIndex()];
87#ifdef PACKING
88            EnsurePackHasSpace(nestedOffset, ifCarryDataBits);
89#endif
90            nestedBlockData->setFramePosition(nestedOffset);
91
92            nestedOffset += ifCarryDataBits;
93            if (cd->maxNestingDepth <= nestedBlockData->maxNestingDepth) cd->maxNestingDepth = nestedBlockData->maxNestingDepth + 1;
94            cd->nested.entries++;
95#ifndef NDEBUG
96            nestedBlockData->dumpCarryData(cerr);
97#endif
98        }
99        else if (While * whileStatement = dyn_cast<While>(stmt)) {
100            const unsigned whileCarryDataBits = enumerate(&whileStatement->getBody(), ifDepth, whileDepth+1);
101            PabloBlockCarryData * nestedBlockData = mCarryInfoVector[whileStatement->getBody().getScopeIndex()];
102            //if (whileStatement->isMultiCarry()) whileCarryDataBits *= whileStatement->getMaxIterations();
103#ifdef PACKING
104            EnsurePackHasSpace(nestedOffset, whileCarryDataBits);
105#endif
106            nestedBlockData->setFramePosition(nestedOffset);
107            nestedOffset += whileCarryDataBits;
108            if (cd->maxNestingDepth <= nestedBlockData->maxNestingDepth) cd->maxNestingDepth = nestedBlockData->maxNestingDepth + 1;
109            cd->nested.entries++;
110#ifndef NDEBUG
111            nestedBlockData->dumpCarryData(cerr);
112#endif
113        }
114    }
115   
116    cd->scopeCarryDataBits = nestedOffset;
117   
118    if (cd->explicitSummaryRequired()) {
119        // Need extra space for the summary variable, always the last
120        // entry within an if block.
121        cd->scopeCarryDataBits = alignCeiling(cd->scopeCarryDataBits, PACK_SIZE);
122        cd->summary.frameOffsetinBits = cd->scopeCarryDataBits;
123        cd->summary.allocatedBits = PACK_SIZE;
124        cd->scopeCarryDataBits += PACK_SIZE;
125    }
126    else {
127        cd->summary.frameOffsetinBits = 0;
128        cd->summary.allocatedBits = cd->scopeCarryDataBits;
129    }
130    return cd->scopeCarryDataBits;
131}
132
133
134/* Entering and leaving blocks. */
135
136void CarryManager::enterScope(PabloBlock * blk) {
137   
138    mCurrentScope = blk;
139    mCarryInfo = mCarryInfoVector[blk->getScopeIndex()];
140    mCurrentFrameIndex += mCarryInfo->getFrameIndex();
141    //std::cerr << "enterScope:  mCurrentFrameIndex = " << mCurrentFrameIndex << std::endl;
142}
143
144void CarryManager::leaveScope() {
145    mCurrentFrameIndex -= mCarryInfo->getFrameIndex();
146    mCurrentScope = mCurrentScope->getParent();
147    mCarryInfo = mCarryInfoVector[mCurrentScope->getScopeIndex()];
148    //std::cerr << "leaveScope:  mCurrentFrameIndex = " << mCurrentFrameIndex << std::endl;
149}
150
151
152/* Helper routines */
153
154unsigned CarryManager::absPosition(unsigned frameOffsetinBits, unsigned relPos) {
155#ifdef PACKING
156    return mCurrentFrameIndex + frameOffsetinBits + relPos;
157#else
158    return mCurrentFrameIndex + frameOffsetinBits/BLOCK_SIZE + relPos;
159#endif
160}
161
162
163unsigned CarryManager::carryOpPosition(unsigned localIndex) {
164    return absPosition(mCarryInfo->addWithCarry.frameOffsetinBits, localIndex);
165}
166
167unsigned CarryManager::advance1Position(unsigned localIndex) {
168    return absPosition(mCarryInfo->advance1.frameOffsetinBits, localIndex);
169}
170
171unsigned CarryManager::shortAdvancePosition(unsigned localIndex) {
172    return absPosition(mCarryInfo->shortAdvance.frameOffsetinBits, localIndex);
173}
174
175unsigned CarryManager::longAdvanceBitBlockPosition(unsigned localIndex) {
176#ifdef PACKING
177    return (mCurrentFrameIndex + mCarryInfo->longAdvance.frameOffsetinBits) / BLOCK_SIZE + localIndex;
178#else
179    return mCurrentFrameIndex + (mCarryInfo->longAdvance.frameOffsetinBits / BLOCK_SIZE) + localIndex;
180#endif
181}
182
183unsigned CarryManager::summaryPosition() {
184    return absPosition(mCarryInfo->summary.frameOffsetinBits, 0);
185}
186
187unsigned CarryManager::summaryBits() {
188    return mCarryInfo->summary.allocatedBits;
189}
190
191
192
193Value * CarryManager::getCarryPack(unsigned packIndex) {
194    if (mCarryInPack[packIndex] == nullptr) {
195        Value * packPtr = mBuilder->CreateGEP(mCarryPackBasePtr, mBuilder->getInt64(packIndex));
196        mCarryPackPtr[packIndex] = packPtr;
197        mCarryInPack[packIndex] = mBuilder->CreateAlignedLoad(packPtr, PACK_SIZE/8);
198    }
199    return mCarryInPack[packIndex];
200}
201
202void CarryManager::storeCarryPack(unsigned packIndex) {
203    mBuilder->CreateAlignedStore(mCarryOutPack[packIndex], mCarryPackPtr[packIndex], PACK_SIZE/8);
204}
205
206Value * CarryManager::getCarryRange(unsigned carryBit_lo, unsigned carryRangeSize) {
207
208    unsigned packIndex = carryBit_lo / PACK_SIZE;
209    unsigned carryOffset = carryBit_lo % PACK_SIZE;
210    unsigned hiOffset = carryBit_lo + carryRangeSize - 1;
211   
212    Value * carryItem = getCarryPack(packIndex);
213    if (carryRangeSize < PACK_SIZE) {
214       carryItem = mBuilder->CreateAnd(carryItem, mBuilder->getInt64((1 << hiOffset) - 1));
215    }
216    if (carryOffset > 0) {
217       carryItem = mBuilder->CreateLShr(carryItem, mBuilder->getInt64(carryOffset));
218    }
219    return carryItem;
220}
221   
222Value * CarryManager::getCarryBit(unsigned carryBitPos) {
223    return getCarryRange(carryBitPos, 1);
224}
225   
226void CarryManager::setCarryBits(unsigned carryBit_lo, Value * bits) {
227   
228    unsigned packIndex = carryBit_lo / PACK_SIZE;
229    unsigned carryOffset = carryBit_lo % PACK_SIZE;
230    if (carryOffset > 0) {
231        bits = mBuilder->CreateLShr(bits, mBuilder->getInt64(carryOffset));
232    }
233    if (mCarryOutPack[packIndex] == nullptr) {
234        mCarryOutPack[packIndex] = bits;
235    }
236    else {
237        mCarryOutPack[packIndex] = mBuilder->CreateOr(mCarryOutPack[packIndex], bits);
238    }
239}
240   
241   
242/* Methods for getting and setting individual carry values. */
243   
244Value * CarryManager::getCarryOpCarryIn(int localIndex) {
245    unsigned posn = carryOpPosition(localIndex);
246#ifdef PACKING
247    return getCarryBit(posn);
248#else
249    return getCarryPack(posn);
250#endif
251}
252   
253   
254void CarryManager::setCarryOpCarryOut(unsigned localIndex, Value * carry_out) {
255    unsigned posn = carryOpPosition(localIndex);
256#ifdef PACKING
257    setCarryBits(posn, carry_out);
258#else
259    mCarryOutPack[posn] = carry_out;
260    if (mCarryInfo->getWhileDepth() == 0) {
261        storeCarryPack(posn);
262    }
263#endif
264}
265
266   
267Value * CarryManager::advanceCarryInCarryOut(int localIndex, int shift_amount, Value * strm) {
268    if (shift_amount == 1) {
269        return unitAdvanceCarryInCarryOut(localIndex, strm);
270    }
271    else if (shift_amount < LongAdvanceBase) {
272        return shortAdvanceCarryInCarryOut(localIndex, shift_amount, strm);
273    }
274    else {
275        return longAdvanceCarryInCarryOut(localIndex, shift_amount, strm);
276    }
277}
278
279Value * CarryManager::unitAdvanceCarryInCarryOut(int localIndex, Value * strm) {
280    unsigned posn = advance1Position(localIndex);
281#ifdef PACKING
282    unsigned offset = posn % PACK_SIZE;
283    unsigned rshift = PACK_SIZE - offset - 1;
284    Value * field = iBuilder->mvmd_extract(PACK_SIZE, strm, BLOCK_SIZE/PACK_SIZE - 1);
285    if (rshift != 0) {
286        field = mBuilder->CreateLShr(field, mBuilder->getInt64(rshift));
287    }
288    if (offset != 0) {
289        field = mBuilder->CreateAnd(field, mBuilder->getInt64(1<<offset));
290    }
291    setCarryBits(posn - offset, field);
292    Value* carry_longint = mBuilder->CreateZExt(getCarryBit(posn), mBuilder->getIntNTy(BLOCK_SIZE));
293    Value* strm_longint = mBuilder->CreateBitCast(strm, mBuilder->getIntNTy(BLOCK_SIZE));
294    Value* adv_longint = mBuilder->CreateOr(mBuilder->CreateShl(strm_longint, 1), carry_longint);
295    result_value = mBuilder->CreateBitCast(adv_longint, mBitBlockType);
296    return result_value;
297#else
298    mCarryOutPack[posn] = strm; 
299    Value * carry_in = getCarryPack(posn);
300    if (mCarryInfo->getWhileDepth() == 0) {
301        storeCarryPack(posn);
302    }
303    Value* result_value;
304   
305#if (BLOCK_SIZE == 128) && !defined(USE_LONG_INTEGER_SHIFT)
306    Value * ahead64 = iBuilder->mvmd_dslli(64, carry_in, strm, 1);
307    result_value = mBuilder->CreateOr(iBuilder->simd_srli(64, ahead64, 63), iBuilder->simd_slli(64, strm, 1));
308#else
309    Value* advanceq_longint = mBuilder->CreateBitCast(carry_in, mBuilder->getIntNTy(BLOCK_SIZE));
310    Value* strm_longint = mBuilder->CreateBitCast(strm, mBuilder->getIntNTy(BLOCK_SIZE));
311    Value* adv_longint = mBuilder->CreateOr(mBuilder->CreateShl(strm_longint, 1), mBuilder->CreateLShr(advanceq_longint, BLOCK_SIZE - 1), "advance");
312    result_value = mBuilder->CreateBitCast(adv_longint, mBitBlockType);
313   
314#endif
315    return result_value;
316#endif
317}
318
319Value * CarryManager::shortAdvanceCarryInCarryOut(int localIndex, int shift_amount, Value * strm) {
320    unsigned posn = shortAdvancePosition(localIndex);
321#ifdef PACKING
322    unsigned offset = posn % PACK_SIZE;
323    unsigned rshift = PACK_SIZE - offset - shift_amount;
324    Value * field = iBuilder->mvmd_extract(PACK_SIZE, strm, BLOCK_SIZE/PACK_SIZE - 1);
325    if (rshift != 0) {
326        field = mBuilder->CreateLShr(field, mBuilder->getInt64(rshift));
327    }
328    if (offset != 0) {
329        field = mBuilder->CreateAnd(field, mBuilder->getInt64(((1<<shift_amount) - 1) << offset));
330    }   
331    setCarryBits(posn - offset, field);
332    Value* carry_longint = mBuilder->CreateZExt(getCarryRange(posn, shift_amount), mBuilder->getIntNTy(BLOCK_SIZE));
333    Value* strm_longint = mBuilder->CreateBitCast(strm, mBuilder->getIntNTy(BLOCK_SIZE));
334    Value* adv_longint = mBuilder->CreateOr(mBuilder->CreateShl(strm_longint, 1), carry_longint);
335    result_value = mBuilder->CreateBitCast(adv_longint, mBitBlockType);
336    return result_value;
337#else
338    mCarryOutPack[posn] = strm; 
339    Value * carry_in = getCarryPack(posn);
340    if (mCarryInfo->getWhileDepth() == 0) {
341        storeCarryPack(posn);
342    }
343    Value* advanceq_longint = mBuilder->CreateBitCast(carry_in, mBuilder->getIntNTy(BLOCK_SIZE));
344    Value* strm_longint = mBuilder->CreateBitCast(strm, mBuilder->getIntNTy(BLOCK_SIZE));
345    Value* adv_longint = mBuilder->CreateOr(mBuilder->CreateShl(strm_longint, shift_amount), mBuilder->CreateLShr(advanceq_longint, BLOCK_SIZE - shift_amount), "advance");
346    return mBuilder->CreateBitCast(adv_longint, mBitBlockType);
347#endif
348}
349   
350
351/*  currently defined in carry_data.h
352 
353 static unsigned power2ceil (unsigned v) {
354 unsigned ceil = 1;
355 while (ceil < v) ceil *= 2;
356 return ceil;
357 }
358 
359 unsigned longAdvanceEntries(unsigned shift_amount) const {
360 return (shift_amount + BLOCK_SIZE - 1)/BLOCK_SIZE;
361 }
362 
363 unsigned longAdvanceBufferSize(unsigned shift_amount)  const {
364 return power2ceil(longAdvanceEntries(shift_amount));
365 }
366 */
367
368   
369Value * CarryManager::longAdvanceCarryInCarryOut(int localIndex, int shift_amount, Value * carry_out) {
370    unsigned carryDataIndex = longAdvanceBitBlockPosition(localIndex);
371    Value * advBaseIndex = mBuilder->getInt64(carryDataIndex);
372    if (shift_amount <= BLOCK_SIZE) {
373        // special case using a single buffer entry and the carry_out value.
374        Value * advanceDataPtr = mBuilder->CreateGEP(mCarryBitBlockPtr, advBaseIndex);
375        Value * carry_block0 = mBuilder->CreateAlignedLoad(advanceDataPtr, BLOCK_SIZE/8);
376        mBuilder->CreateAlignedStore(carry_out, advanceDataPtr, BLOCK_SIZE/8);
377        /* Very special case - no combine */
378        if (shift_amount == BLOCK_SIZE) return carry_block0;
379        Value* block0_shr = mBuilder->CreateLShr(mBuilder->CreateBitCast(carry_block0, mBuilder->getIntNTy(BLOCK_SIZE)), BLOCK_SIZE - shift_amount);
380        Value* block1_shl = mBuilder->CreateShl(mBuilder->CreateBitCast(carry_out, mBuilder->getIntNTy(BLOCK_SIZE)), shift_amount);
381        return mBuilder->CreateBitCast(mBuilder->CreateOr(block1_shl, block0_shr), mBitBlockType);
382    }
383    // We need a buffer of at least two elements for storing the advance data.
384    const unsigned block_shift = shift_amount % BLOCK_SIZE;
385    const unsigned advanceEntries = mCarryInfo->longAdvanceEntries(shift_amount);
386    const unsigned bufsize = mCarryInfo->longAdvanceBufferSize(shift_amount);
387    Value * indexMask = mBuilder->getInt64(bufsize - 1);  // A mask to implement circular buffer indexing
388    Value * loadIndex0 = mBuilder->CreateAdd(mBuilder->CreateAnd(mBuilder->CreateSub(mBlockNo, mBuilder->getInt64(advanceEntries)), indexMask), advBaseIndex);
389    Value * storeIndex = mBuilder->CreateAdd(mBuilder->CreateAnd(mBlockNo, indexMask), advBaseIndex);
390    Value * carry_block0 = mBuilder->CreateAlignedLoad(mBuilder->CreateGEP(mCarryBitBlockPtr, loadIndex0), BLOCK_SIZE/8);
391    // If the long advance is an exact multiple of BLOCK_SIZE, we simply return the oldest
392    // block in the long advance carry data area. 
393    if (block_shift == 0) {
394        mBuilder->CreateAlignedStore(carry_out, mBuilder->CreateGEP(mCarryBitBlockPtr, storeIndex), BLOCK_SIZE/8);
395        return carry_block0;
396    }
397    // Otherwise we need to combine data from the two oldest blocks.
398    Value * loadIndex1 = mBuilder->CreateAdd(mBuilder->CreateAnd(mBuilder->CreateSub(mBlockNo, mBuilder->getInt64(advanceEntries-1)), indexMask), advBaseIndex);
399    Value * carry_block1 = mBuilder->CreateAlignedLoad(mBuilder->CreateGEP(mCarryBitBlockPtr, loadIndex1), BLOCK_SIZE/8);
400    Value* block0_shr = mBuilder->CreateLShr(mBuilder->CreateBitCast(carry_block0, mBuilder->getIntNTy(BLOCK_SIZE)), BLOCK_SIZE - block_shift);
401    Value* block1_shl = mBuilder->CreateShl(mBuilder->CreateBitCast(carry_block1, mBuilder->getIntNTy(BLOCK_SIZE)), block_shift);
402    mBuilder->CreateAlignedStore(carry_out, mBuilder->CreateGEP(mCarryBitBlockPtr, storeIndex), BLOCK_SIZE/8);
403    return mBuilder->CreateBitCast(mBuilder->CreateOr(block1_shl, block0_shr), mBitBlockType);
404}
405   
406
407/* Methods for getting and setting carry summary values */
408   
409bool CarryManager::blockHasCarries(){
410    return mCarryInfo->blockHasCarries();
411} 
412
413
414Value * CarryManager::getCarrySummaryExpr() {
415    unsigned summary_posn = summaryPosition();
416#ifdef PACKING
417    return getCarryRange(summary_posn, getSummaryBits());
418#else
419    return getCarryPack(summary_posn);
420#endif
421}
422
423void CarryManager::addSummaryPhiIfNeeded(BasicBlock * ifEntryBlock, BasicBlock * ifBodyFinalBlock) {
424    if ((mCarryInfo->getIfDepth() <= 1) || !mCarryInfo->blockHasCarries()){
425        // For ifDepth == 1, the parent does not need a summary as it is not itself within an if.
426        // Therefore, it doesn't need access to this block's summary in building its own.
427        return;
428    }
429    const unsigned carrySummaryIndex = summaryPosition();
430    PHINode * summary_phi = mBuilder->CreatePHI(mBitBlockType, 2, "summary");
431    summary_phi->addIncoming(mZeroInitializer, ifEntryBlock);
432    summary_phi->addIncoming(mCarryOutPack[carrySummaryIndex], ifBodyFinalBlock);
433    mCarryOutPack[carrySummaryIndex] = summary_phi;
434}
435
436void CarryManager::generateCarryOutSummaryCodeIfNeeded() {
437   
438    if (!mCarryInfo->explicitSummaryRequired()) {
439        // An explicit summary may not be required, if there is a single carry
440        // operation within the block, or the carries are packed and all carry
441        // bits fit within a single pack.
442        return;
443    }
444   
445    const unsigned carrySummaryIndex = summaryPosition();
446   
447    Value * carry_summary = mZeroInitializer;
448   
449    if (mCarryInfo->blockHasLongAdvances()) { // Force if entry
450#ifdef PACKING
451        carry_summary = mBuilder->getInt64(-1);
452#else
453        carry_summary = mOneInitializer;
454#endif
455    }
456    else {
457        auto localCarryIndex = mCurrentFrameIndex + mCarryInfo->getLocalCarryPackIndex();
458        auto localCarryPacks = mCarryInfo->getLocalCarryPackCount();
459        if (localCarryPacks > 0) {
460            carry_summary = mCarryOutPack[localCarryIndex];
461            for (auto i = 1; i < localCarryPacks; i++) {
462                //carry_summary = mBuilder->CreateOr(carry_summary, mPabloBlock->mCarryOutPack[i]);           
463                carry_summary = mBuilder->CreateOr(carry_summary, mCarryOutPack[localCarryIndex+i]);
464            }
465        }
466        for (Statement * stmt : *mCurrentScope) {
467            if (If * innerIf = dyn_cast<If>(stmt)) {
468                PabloBlock * inner_blk = & innerIf->getBody();
469                enterScope(inner_blk);
470                if (blockHasCarries()) {
471                  carry_summary = mBuilder->CreateOr(carry_summary, mCarryOutPack[summaryPosition()]);
472                }
473                leaveScope();
474            }
475            else if (While * innerWhile = dyn_cast<While>(stmt)) {
476                PabloBlock * inner_blk = & innerWhile->getBody();
477                enterScope(inner_blk);
478                if (blockHasCarries()) {
479                    carry_summary = mBuilder->CreateOr(carry_summary, mCarryOutPack[summaryPosition()]);
480                }
481                leaveScope();
482            }
483        }
484    }
485    // Calculation of the carry out summary is complete.   Store it and make it
486    // available in case it must included by parent blocks.
487    mCarryOutPack[carrySummaryIndex] = carry_summary;
488    storeCarryPack(carrySummaryIndex);
489}
490
491
492
493void CarryManager::ensureCarriesLoadedRecursive() {
494    const unsigned scopeCarryPacks = mCarryInfo->getScopeCarryPackCount();
495    if (mCarryInfo->getWhileDepth() == 1) {
496        for (auto i = mCurrentFrameIndex; i < mCurrentFrameIndex + scopeCarryPacks; ++i) {
497            getCarryPack(i);
498        }
499    }
500}
501
502
503void CarryManager::initializeCarryDataPhisAtWhileEntry(BasicBlock * whileEntryBlock) {
504    const unsigned scopeCarryPacks = mCarryInfo->getScopeCarryPackCount();
505    mCarryOutAccumPhis.resize(scopeCarryPacks);
506#ifdef SET_WHILE_CARRY_IN_TO_ZERO_AFTER_FIRST_ITERATION
507    mCarryInPhis.resize(scopeCarryPacks);
508#endif
509    for (unsigned index = 0; index < scopeCarryPacks; ++index) {
510#ifdef SET_WHILE_CARRY_IN_TO_ZERO_AFTER_FIRST_ITERATION
511        PHINode * phi_in = mBuilder->CreatePHI(mBitBlockType, 2);
512        phi_in->addIncoming(mCarryInPack[mCurrentFrameIndex+index], whileEntryBlock);
513        mCarryInPhis[index] = phi_in;
514#endif
515        PHINode * phi_out = mBuilder->CreatePHI(mBitBlockType, 2);
516        phi_out->addIncoming(mZeroInitializer, whileEntryBlock);
517        mCarryOutAccumPhis[index] = phi_out;
518    }
519}
520
521
522void CarryManager::extendCarryDataPhisAtWhileBodyFinalBlock(BasicBlock * whileBodyFinalBlock) {
523    const unsigned scopeCarryPacks = mCarryInfo->getScopeCarryPackCount();
524    for (unsigned index = 0; index < scopeCarryPacks; ++index) {
525#ifdef SET_WHILE_CARRY_IN_TO_ZERO_AFTER_FIRST_ITERATION
526        mCarryInPhis[index]->addIncoming(mZeroInitializer, whileBodyFinalBlock);
527#endif
528        PHINode * phi = mCarryOutAccumPhis[index];
529        Value * carryOut = mBuilder->CreateOr(phi, mCarryOutPack[mCurrentFrameIndex+index]);
530        phi->addIncoming(carryOut, whileBodyFinalBlock);
531        mCarryOutPack[mCurrentFrameIndex+index] = carryOut;
532    }
533}
534
535void CarryManager::ensureCarriesStoredRecursive() {
536    const unsigned scopeCarryPacks = mCarryInfo->getScopeCarryPackCount();
537    if (mCarryInfo->getWhileDepth() == 1) {
538        for (auto i = mCurrentFrameIndex; i < mCurrentFrameIndex + scopeCarryPacks; ++i) {
539            storeCarryPack(i);
540        }
541    }
542}
543
544}
545
Note: See TracBrowser for help on using the repository browser.