source: icGREP/icgrep-devel/icgrep/pablo/carrypack_manager.h @ 5972

Last change on this file since 5972 was 5708, checked in by cameron, 2 years ago

Progress on indexed advance

File size: 7.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#ifndef CARRY_MANAGER_H
8#define CARRY_MANAGER_H
9
10#include <pablo/carry_data.h>
11#include <memory>
12#include <vector>
13namespace IDISA { class IDISA_Builder; }
14namespace llvm { class BasicBlock; }
15namespace llvm { class ConstantInt; }
16namespace llvm { class Function; }
17namespace llvm { class PHINode; }
18namespace llvm { class StructType; }
19namespace llvm { class Type; }
20namespace llvm { class Value; }
21namespace pablo { class Advance; }
22namespace pablo { class IndexedAdvance; }
23namespace pablo { class PabloBlock; }
24namespace pablo { class PabloKernel; }
25namespace pablo { class Statement; }
26namespace pablo { class CarryProducingStatement; }
27namespace kernel { class KernelBuilder; }
28
29/*
30 * Carry Data Manager.
31 *
32 * Each PabloBlock (Main, If, While) has a contiguous data area for carry information.
33 * The data area may be at a fixed or variable base offset from the base of the
34 * main function carry data area.
35 * The data area for each block consists of contiguous space for the local carries and
36 * advances of the block plus the areas of any ifs/whiles nested within the block.
37
38*/
39
40namespace pablo {
41
42class CarryManager {
43
44    enum { LONG_ADVANCE_BASE = 64 };
45
46public:
47     
48    struct CarryGroup {
49        llvm::Value * carryIn;
50        llvm::Value * carryOut;
51        unsigned packedSize;
52        unsigned groupSize;
53        unsigned frameIndex;
54        CarryGroup() = default;
55    };
56
57    using CarryFrame = std::pair<llvm::Value *, std::vector<llvm::Value *>>;
58
59    CarryManager() noexcept;
60
61    void initializeCarryData(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, PabloKernel * const kernel);
62
63    void releaseCarryData(const std::unique_ptr<kernel::KernelBuilder> & idb);
64
65    void initializeCodeGen(const std::unique_ptr<kernel::KernelBuilder> & iBuilder);
66
67    void finalizeCodeGen(const std::unique_ptr<kernel::KernelBuilder> & iBuilder);
68
69    /* Entering and leaving loops. */
70
71    void enterLoopScope(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, const PabloBlock * const scope);
72
73    void enterLoopBody(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, llvm::BasicBlock * const entryBlock);
74
75    void leaveLoopBody(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, llvm::BasicBlock * const exitBlock);
76
77    void leaveLoopScope(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, llvm::BasicBlock * const entryBlock, llvm::BasicBlock * const exitBlock);
78
79    /* Entering and leaving ifs. */
80
81    void enterIfScope(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, const PabloBlock * const scope);
82
83    void enterIfBody(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, llvm::BasicBlock * const entryBlock);
84
85    void leaveIfBody(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, llvm::BasicBlock * const exitBlock);
86
87    void leaveIfScope(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, llvm::BasicBlock * const entryBlock, llvm::BasicBlock * const exitBlock);
88
89    /* Methods for processing individual carry-generating operations. */
90   
91    llvm::Value * addCarryInCarryOut(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, const CarryProducingStatement * const op, llvm::Value * const e1, llvm::Value * const e2);
92
93    llvm::Value * advanceCarryInCarryOut(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, const Advance * advance, llvm::Value * const strm);
94 
95    llvm::Value * indexedAdvanceCarryInCarryOut(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, const IndexedAdvance * advance, llvm::Value * const strm, llvm::Value * const index_strm);
96
97    /* Methods for getting and setting carry summary values for If statements */
98         
99    llvm::Value * generateSummaryTest(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, llvm::Value * condition);
100
101protected:
102
103    static unsigned getScopeCount(const PabloBlock * const scope, unsigned index = 0);
104
105    unsigned assignDefaultCarryGroups(PabloBlock * const scope, const unsigned ifDepth = 0, const unsigned loopDepth = 0, unsigned carryGroups = 0);
106
107    static bool hasIterationSpecificAssignment(const PabloBlock * const scope);
108
109    llvm::StructType * analyse(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, const PabloBlock * const scope,
110                               const unsigned ifDepth = 0, const unsigned whileDepth = 0, const bool isNestedWithinNonCarryCollapsingLoop = false);
111
112    /* Entering and leaving scopes. */
113    void enterScope(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, const PabloBlock * const scope);
114    void leaveScope(const std::unique_ptr<kernel::KernelBuilder> & iBuilder);
115
116    /* Methods for processing individual carry-generating operations. */
117    llvm::Value * getCarryIn(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, const pablo::CarryProducingStatement * const op);
118    llvm::Value * getCarryInGroup(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, const pablo::CarryProducingStatement * const op);
119    llvm::Value * readCarryIn(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, const CarryProducingStatement * const op);
120
121    void setCarryOut(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, const pablo::CarryProducingStatement * const op, llvm::Value * carryOut);
122    llvm::Value * getCarryOutGroupPtr(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, const pablo::CarryProducingStatement * const op);
123    llvm::Value * writeCarryOut(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, const CarryProducingStatement * const op, llvm::Value * carryOut);
124
125    llvm::Value * longAdvanceCarryInCarryOut(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, llvm::Value * const value, const unsigned shiftAmount);
126
127    /* Summary handling routines */
128    llvm::Value * readCarryInSummary(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, llvm::ConstantInt *index);
129    void addToCarryOutSummary(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, llvm::Value * const value);
130    void writeCarryOutSummary(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, llvm::Value * const summary, llvm::ConstantInt * index);
131
132private:
133
134    const PabloKernel *                             mKernel;
135
136    unsigned                                        mVectorWidth;
137    unsigned                                        mElementWidth;
138
139    llvm::Value *                                   mCurrentFrame;
140    std::vector<llvm::Value *>                      mCurrentFrameOffset;
141    unsigned                                        mCurrentFrameIndex;
142    std::vector<CarryGroup>                         mCarryGroup;
143
144    const PabloBlock *                              mCurrentScope;
145    CarryData *                                     mCarryInfo;
146
147    llvm::Value *                                   mNextSummaryTest;
148
149    unsigned                                        mIfDepth;
150
151    bool                                            mHasLongAdvance;
152    unsigned                                        mIndexedLongAdvanceTotal;
153    unsigned                                        mIndexedLongAdvanceIndex;
154    bool                                            mHasNonCarryCollapsingLoops;
155    bool                                            mHasLoop;
156    unsigned                                        mLoopDepth;
157    std::array<llvm::Value *, 2>                    mLoopSelector;
158
159    std::vector<llvm::PHINode *>                    mLoopIndicies;
160
161    std::vector<CarryData>                          mCarryMetadata;
162
163    std::vector<CarryFrame>                         mNonCarryCollapsingLoopCarryFrameStack;
164
165    unsigned                                        mCarryScopes;
166    std::vector<unsigned>                           mCarryScopeIndex;
167
168    std::vector<llvm::Value *>                      mCarrySummaryStack;
169};
170
171}
172
173#endif // CARRY_MANAGER_H
Note: See TracBrowser for help on using the repository browser.