source: icGREP/icgrep-devel/icgrep/pablo/carry_data.h @ 4704

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

Carry manager fixes, restructuring

File size: 4.7 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#ifndef CARRY_DATA_H
8#define CARRY_DATA_H
9#include <include/simd-lib/bitblock.hpp>
10#include <stdexcept>
11#include <iostream>
12#include <ostream>
13#include <llvm/Support/raw_os_ostream.h>
14#include <llvm/IR/Module.h>
15
16/*
17 * Carry Data system.
18 *
19 * Each PabloBlock (Main, If, While) has a contiguous data area for carry information.
20 * The data area may be at a fixed or variable base offset from the base of the
21 * main function carry data area.
22 * The data area for each block consists of contiguous space for the local carries and
23 * advances of the block plus the areas of any ifs/whiles nested within the block.
24
25*/
26unsigned const LongAdvanceBase = 64;
27
28//#define PACKING
29
30#ifdef PACKING
31const unsigned PACK_SIZE = 64;
32#else
33const unsigned PACK_SIZE = BLOCK_SIZE;
34#endif
35
36
37static unsigned power2ceil (unsigned v) {
38    unsigned ceil = 1;
39    while (ceil < v) ceil *= 2;
40    return ceil;
41}
42
43static unsigned alignCeiling(unsigned toAlign, unsigned alignment) {
44    return ((toAlign - 1) | (alignment - 1)) + 1;
45}
46
47static unsigned fullOrPartialBlocks(unsigned bits, unsigned block_size) {
48    return alignCeiling(bits, block_size) / block_size;
49}
50
51#ifdef PACKING
52static void EnsurePackHasSpace(unsigned & packedTotalBits, unsigned addedBits) {
53    unsigned bitsInCurrentPack = packedTotalBits % PACK_SIZE;
54    if ((bitsInCurrentPack > 0) && (bitsInCurrentPack + addedBits > PACK_SIZE)) {
55        packedTotalBits = alignCeiling(packedTotalBits, PACK_SIZE);
56    }
57}
58#endif
59
60
61namespace pablo {
62
63class PabloBlock;
64
65class PabloBlockCarryData {
66public:
67    PabloBlockCarryData(PabloBlock * b):
68                           theScope(b), framePosition(0),
69                           ifDepth(0), whileDepth (0), maxNestingDepth(0),
70                           longAdvance({0, 0, 0}),
71                           shortAdvance({0, 0, 0}),
72                           advance1({0, 0}),
73                           addWithCarry({0, 0}),
74                           nested({0, 0, 0}),
75                           summary({0, 0}),
76                           scopeCarryDataSize(0)
77    {enumerateLocal();}
78       
79    friend class CarryManager;
80   
81    void enumerateLocal();
82    void dumpCarryData(llvm::raw_ostream & strm);
83   
84    unsigned getFrameIndex()  const {
85        return framePosition;
86    }
87   
88    void setFramePosition(unsigned p) {
89        framePosition = p;
90    }
91   
92    unsigned getIfDepth()  const {
93        return ifDepth;
94    }
95   
96    void setIfDepth(unsigned d) {
97        ifDepth = d;
98    }
99   
100    unsigned getWhileDepth()  const {
101        return whileDepth;
102    }
103       
104    void setWhileDepth(unsigned d) {
105        whileDepth = d;
106    }
107   
108    unsigned longAdvanceEntries(unsigned shift_amount) const {
109        return fullOrPartialBlocks(shift_amount, BLOCK_SIZE);
110    }
111   
112    unsigned longAdvanceBufferSize(unsigned shift_amount)  const {
113        return power2ceil(longAdvanceEntries(shift_amount));
114    }
115   
116    bool blockHasLongAdvances() const { return longAdvance.entries > 0;}
117   
118    unsigned getLocalCarryPackIndex () { 
119#ifdef PACKING
120        return shortAdvance.frameOffset / PACK_SIZE;
121#else
122        return shortAdvance.frameOffset;
123#endif
124    }
125
126    unsigned getLocalCarryPackCount () { 
127#ifdef PACKING
128        return fullOrPartialBlocks(nested.frameOffset, PACK_SIZE) - shortAdvance.frameOffset / PACK_SIZE;
129#else
130        return nested.frameOffset - shortAdvance.frameOffset;
131#endif
132    }
133   
134    unsigned getScopeCarryPackCount () { 
135#ifdef PACKING
136        return fullOrPartialBlocks(scopeCarryDataSize, PACK_SIZE);
137#else
138        return scopeCarryDataSize;
139#endif
140    }
141   
142    bool blockHasCarries() const { return scopeCarryDataSize > 0;}
143   
144    bool explicitSummaryRequired() const { 
145#ifdef PACKING
146        return (ifDepth > 0) && (scopeCarryDataSize > PACK_SIZE);
147#else
148        return (ifDepth > 0) && (scopeCarryDataSize > 1);
149#endif
150    }
151   
152protected:
153   
154    PabloBlock * theScope;
155   
156    unsigned framePosition;
157   
158    unsigned ifDepth;
159    unsigned whileDepth;
160    unsigned maxNestingDepth;   
161   
162    struct {unsigned frameOffset; unsigned entries; unsigned allocatedBitBlocks;} longAdvance;
163    struct {unsigned frameOffset; unsigned entries; unsigned allocatedBits;} shortAdvance;
164    struct {unsigned frameOffset; unsigned entries;} advance1;
165    struct {unsigned frameOffset; unsigned entries;} addWithCarry;
166    struct {unsigned frameOffset; unsigned entries; unsigned allocatedBits;} nested;
167    struct {unsigned frameOffset; unsigned allocatedBits;} summary;
168
169    unsigned scopeCarryDataSize;
170   
171    llvm::Value * ifEntryPack;
172   
173};
174
175
176}
177
178
179#endif // CARRY_DATA_H
Note: See TracBrowser for help on using the repository browser.