Ignore:
Timestamp:
Jul 7, 2015, 8:07:25 PM (4 years ago)
Author:
cameron
Message:

Carry Manager system integrated into Pablo compiler

File:
1 edited

Legend:

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

    r4644 r4647  
    1212#include <carry_manager.h>
    1313#include <pabloAST.h>
     14#include <iostream>
    1415
    1516namespace pablo {
     
    4647Value * CarryManager::getCarryOpCarryIn(PabloBlock * blk, int localIndex) {
    4748    PabloBlockCarryData & cd = blk->carryData;
     49    if (cd.getWhileDepth() == 0) {
     50       Value * packPtr = mBuilder->CreateGEP(mCarryDataPtr, mBuilder->getInt64(cd.carryOpCarryDataOffset(localIndex)));
     51       mCarryInVector[cd.carryOpCarryDataOffset(localIndex)] = mBuilder->CreateAlignedLoad(packPtr, BLOCK_SIZE/8);
     52    }
    4853    return mCarryInVector[cd.carryOpCarryDataOffset(localIndex)];
    4954}
     
    5156Value * CarryManager::getUnitAdvanceCarryIn(PabloBlock * blk, int localIndex) {
    5257    PabloBlockCarryData & cd = blk->carryData;
     58    if (cd.getWhileDepth() == 0) {
     59       Value * packPtr = mBuilder->CreateGEP(mCarryDataPtr, mBuilder->getInt64(cd.unitAdvanceCarryDataOffset(localIndex)));
     60       mCarryInVector[cd.unitAdvanceCarryDataOffset(localIndex)] = mBuilder->CreateAlignedLoad(packPtr, BLOCK_SIZE/8);
     61    }
    5362    return mCarryInVector[cd.unitAdvanceCarryDataOffset(localIndex)];
    5463}
     
    5665Value * CarryManager::getShortAdvanceCarryIn(PabloBlock * blk, int localIndex, int shift_amount) {
    5766    PabloBlockCarryData & cd = blk->carryData;
     67    if (cd.getWhileDepth() == 0) {
     68       Value * packPtr = mBuilder->CreateGEP(mCarryDataPtr, mBuilder->getInt64(cd.shortAdvanceCarryDataOffset(localIndex)));
     69       mCarryInVector[cd.shortAdvanceCarryDataOffset(localIndex)] = mBuilder->CreateAlignedLoad(packPtr, BLOCK_SIZE/8);
     70    }
    5871    return mCarryInVector[cd.shortAdvanceCarryDataOffset(localIndex)];
    5972}
    6073
     74void CarryManager::setCarryOpCarryOut(PabloBlock * blk, unsigned idx, Value * carry_out) {
     75    PabloBlockCarryData & cd = blk->carryData;
     76    mCarryOutVector[cd.carryOpCarryDataOffset(idx)] = carry_out;
     77    if (cd.getWhileDepth() == 0) {
     78       Value * packPtr = mBuilder->CreateGEP(mCarryDataPtr, mBuilder->getInt64(cd.carryOpCarryDataOffset(idx)));
     79       mBuilder->CreateAlignedStore(carry_out, packPtr, BLOCK_SIZE/8);
     80    }
     81}
     82
     83void CarryManager::setUnitAdvanceCarryOut(PabloBlock * blk, unsigned idx, Value * carry_out) {
     84    PabloBlockCarryData & cd = blk->carryData;
     85    mCarryOutVector[cd.unitAdvanceCarryDataOffset(idx)] = carry_out;
     86    if (cd.getWhileDepth() == 0) {
     87       Value * packPtr = mBuilder->CreateGEP(mCarryDataPtr, mBuilder->getInt64(cd.unitAdvanceCarryDataOffset(idx)));
     88       mBuilder->CreateAlignedStore(carry_out, packPtr, BLOCK_SIZE/8);
     89    }
     90}
     91
     92void CarryManager::setShortAdvanceCarryOut(PabloBlock * blk, unsigned idx, int shift_amount, Value * carry_out) {
     93    PabloBlockCarryData & cd = blk->carryData;
     94    mCarryOutVector[cd.shortAdvanceCarryDataOffset(idx)] = carry_out;
     95    if (cd.getWhileDepth() == 0) {
     96       Value * packPtr = mBuilder->CreateGEP(mCarryDataPtr, mBuilder->getInt64(cd.shortAdvanceCarryDataOffset(idx)));
     97       mBuilder->CreateAlignedStore(carry_out, packPtr, BLOCK_SIZE/8);
     98    }
     99}
     100   
    61101/*
    62 static unsigned power2ceil (unsigned v) {
    63     unsigned ceil = 1;
    64     while (ceil < v) ceil *= 2;
    65     return ceil;
    66 }
    67 
    68 unsigned longAdvanceEntries(unsigned shift_amount) const {
    69     return (shift_amount + BLOCK_SIZE - 1)/BLOCK_SIZE;
    70 }
    71    
    72 unsigned longAdvanceBufferSize(unsigned shift_amount)  const {
    73     return power2ceil(longAdvanceEntries(shift_amount));
    74 }
    75 */
    76 
    77 Value * CarryManager::getLongAdvanceCarryIn(PabloBlock * blk, int localIndex, int shift_amount) {
    78     PabloBlockCarryData & cd = blk->carryData;
     102 static unsigned power2ceil (unsigned v) {
     103 unsigned ceil = 1;
     104 while (ceil < v) ceil *= 2;
     105 return ceil;
     106 }
     107 
     108 unsigned longAdvanceEntries(unsigned shift_amount) const {
     109 return (shift_amount + BLOCK_SIZE - 1)/BLOCK_SIZE;
     110 }
     111 
     112 unsigned longAdvanceBufferSize(unsigned shift_amount)  const {
     113 return power2ceil(longAdvanceEntries(shift_amount));
     114 }
     115 */
     116
     117Value * CarryManager::longAdvanceCarryInCarryOut(PabloBlock * blk, int localIndex, int shift_amount, Value * carry_out) {
     118    PabloBlockCarryData & cd = blk->carryData;
     119    Value * advBaseIndex = mBuilder->getInt64(cd.longAdvanceCarryDataOffset(localIndex));
     120    if (shift_amount <= BLOCK_SIZE) {
     121        // special case using a single buffer entry and the carry_out value.
     122        Value * advanceDataPtr = mBuilder->CreateGEP(mCarryDataPtr, advBaseIndex);
     123        Value * carry_block0 = mBuilder->CreateAlignedLoad(advanceDataPtr, BLOCK_SIZE/8);
     124        mBuilder->CreateAlignedStore(carry_out, advanceDataPtr, BLOCK_SIZE/8);
     125        /* Very special case - no combine */
     126        if (shift_amount == BLOCK_SIZE) return carry_block0;
     127        Value* block0_shr = mBuilder->CreateLShr(mBuilder->CreateBitCast(carry_block0, mBuilder->getIntNTy(BLOCK_SIZE)), BLOCK_SIZE - shift_amount);
     128        Value* block1_shl = mBuilder->CreateShl(mBuilder->CreateBitCast(carry_out, mBuilder->getIntNTy(BLOCK_SIZE)), shift_amount);
     129        return mBuilder->CreateBitCast(mBuilder->CreateOr(block1_shl, block0_shr), mBitBlockType);
     130    }
     131    // We need a buffer of at least two elements for storing the advance data.
    79132    const unsigned block_shift = shift_amount % BLOCK_SIZE;
    80133    const unsigned advanceEntries = cd.longAdvanceEntries(shift_amount);
    81134    const unsigned bufsize = cd.longAdvanceBufferSize(shift_amount);
    82135    Value * indexMask = mBuilder->getInt64(bufsize - 1);  // A mask to implement circular buffer indexing
    83     Value * advBaseIndex = mBuilder->getInt64(cd.longAdvanceCarryDataOffset(localIndex));
    84136    Value * loadIndex0 = mBuilder->CreateAdd(mBuilder->CreateAnd(mBuilder->CreateSub(mBlockNo, mBuilder->getInt64(advanceEntries)), indexMask), advBaseIndex);
     137    Value * storeIndex = mBuilder->CreateAdd(mBuilder->CreateAnd(mBlockNo, indexMask), advBaseIndex);
    85138    Value * carry_block0 = mBuilder->CreateAlignedLoad(mBuilder->CreateGEP(mCarryDataPtr, loadIndex0), BLOCK_SIZE/8);
    86139    // If the long advance is an exact multiple of BLOCK_SIZE, we simply return the oldest
    87     // block in the long advance carry data area.
    88     if (block_shift == 0) return carry_block0;
    89     Value* block0_shr = mBuilder->CreateLShr(mBuilder->CreateBitCast(carry_block0, mBuilder->getIntNTy(BLOCK_SIZE)), BLOCK_SIZE - block_shift);
    90     if (advanceEntries == 1) {
    91         return mBuilder->CreateBitCast(block0_shr, mBitBlockType);
     140    // block in the long advance carry data area. 
     141    if (block_shift == 0) {
     142        mBuilder->CreateAlignedStore(carry_out, mBuilder->CreateGEP(mCarryDataPtr, storeIndex), BLOCK_SIZE/8);
     143        return carry_block0;
    92144    }
    93145    // Otherwise we need to combine data from the two oldest blocks.
    94146    Value * loadIndex1 = mBuilder->CreateAdd(mBuilder->CreateAnd(mBuilder->CreateSub(mBlockNo, mBuilder->getInt64(advanceEntries-1)), indexMask), advBaseIndex);
    95147    Value * carry_block1 = mBuilder->CreateAlignedLoad(mBuilder->CreateGEP(mCarryDataPtr, loadIndex1), BLOCK_SIZE/8);
     148    Value* block0_shr = mBuilder->CreateLShr(mBuilder->CreateBitCast(carry_block0, mBuilder->getIntNTy(BLOCK_SIZE)), BLOCK_SIZE - block_shift);
    96149    Value* block1_shl = mBuilder->CreateShl(mBuilder->CreateBitCast(carry_block1, mBuilder->getIntNTy(BLOCK_SIZE)), block_shift);
     150    mBuilder->CreateAlignedStore(carry_out, mBuilder->CreateGEP(mCarryDataPtr, storeIndex), BLOCK_SIZE/8);
    97151    return mBuilder->CreateBitCast(mBuilder->CreateOr(block1_shl, block0_shr), mBitBlockType);
    98152}
    99 
    100 void CarryManager::setCarryOpCarryOut(PabloBlock * blk, unsigned idx, Value * carry_out) {
    101     PabloBlockCarryData & cd = blk->carryData;
    102     mCarryOutVector[cd.carryOpCarryDataOffset(idx)] = carry_out;
    103 }
    104 
    105 void CarryManager::setUnitAdvanceCarryOut(PabloBlock * blk, unsigned idx, Value * carry_out) {
    106     PabloBlockCarryData & cd = blk->carryData;
    107     mCarryOutVector[cd.unitAdvanceCarryDataOffset(idx)] = carry_out;
    108 }
    109 
    110 void CarryManager::setShortAdvanceCarryOut(PabloBlock * blk, unsigned idx, int shift_amount, Value * carry_out) {
    111     PabloBlockCarryData & cd = blk->carryData;
    112     mCarryOutVector[cd.shortAdvanceCarryDataOffset(idx)] = carry_out;
    113 }
    114 
    115 void CarryManager::setLongAdvanceCarryOut(PabloBlock * blk, unsigned idx, int shift_amount, Value * carry_out){
    116     PabloBlockCarryData & cd = blk->carryData;
    117     const unsigned bufsize = cd.longAdvanceBufferSize(shift_amount);
    118     Value * indexMask = mBuilder->getInt64(bufsize - 1);  // Mask to implement circular buffer indexing
    119     Value * advBaseIndex = mBuilder->getInt64(cd.longAdvanceCarryDataOffset(idx));
    120     Value * storeIndex = mBuilder->CreateAdd(mBuilder->CreateAnd(mBlockNo, indexMask), advBaseIndex);
    121     mBuilder->CreateAlignedStore(carry_out, mBuilder->CreateGEP(mCarryDataPtr, storeIndex), BLOCK_SIZE/8);
    122 }
    123 
     153   
    124154
    125155/* Methods for getting and setting carry summary values */
     
    180210                carry_summary = mBuilder->CreateOr(carry_summary, mCarryOutVector[baseCarryDataIdx+i]);
    181211            }
    182        
     212        }
    183213        for (Statement * stmt : blk) {
    184214            if (If * innerIf = dyn_cast<If>(stmt)) {
     
    202232    Value * packPtr = mBuilder->CreateGEP(mCarryDataPtr, mBuilder->getInt64(carrySummaryIndex));
    203233    mBuilder->CreateAlignedStore(carry_summary, packPtr, BLOCK_SIZE/8);
    204     }
    205234}
    206235
    207236void CarryManager::ensureCarriesLoadedLocal(PabloBlock & blk) {
     237#if 0
    208238    const PabloBlockCarryData & cd = blk.carryData;
    209239    const unsigned baseCarryDataIdx = cd.getBlockCarryDataIndex();
     
    216246        mCarryInVector[i] = mBuilder->CreateAlignedLoad(mBuilder->CreateGEP(mCarryDataPtr, mBuilder->getInt64(i)), BLOCK_SIZE/8, false);
    217247    }
     248#endif
    218249}
    219250
    220251void CarryManager::ensureCarriesStoredLocal(PabloBlock & blk) {
     252#if 0
    221253    const PabloBlockCarryData & cd = blk.carryData;
    222254    const unsigned baseCarryDataIdx = cd.getBlockCarryDataIndex();
     
    234266        mBuilder->CreateAlignedStore(mCarryOutVector[carrySummaryIndex], summaryPtr, BLOCK_SIZE/8, false);
    235267    }
     268#endif
    236269}
    237270
     
    241274    const unsigned baseCarryDataIdx = cd.getBlockCarryDataIndex();
    242275    const unsigned totalCarryDataSize = cd.getTotalCarryDataSize();
    243     if (cd.getWhileDepth() == 0) {
     276    if (cd.getWhileDepth() == 1) {
    244277        for (auto i = baseCarryDataIdx; i < baseCarryDataIdx + totalCarryDataSize; ++i) {
    245278            mCarryInVector[i] = mBuilder->CreateAlignedLoad(mBuilder->CreateGEP(mCarryDataPtr, mBuilder->getInt64(i)), BLOCK_SIZE/8, false);
     
    285318    const unsigned baseCarryDataIdx = cd.getBlockCarryDataIndex();
    286319    const unsigned totalCarryDataSize = cd.getTotalCarryDataSize();
    287     if (cd.getWhileDepth() == 0) {
     320    if (cd.getWhileDepth() == 1) {
    288321        for (auto i = baseCarryDataIdx; i < baseCarryDataIdx + totalCarryDataSize; ++i) {
    289322            Value * storePtr = mBuilder->CreateGEP(mCarryDataPtr, mBuilder->getInt64(i));
Note: See TracChangeset for help on using the changeset viewer.