source: icGREP/icgrep-devel/icgrep/pablo/carry_manager.h @ 5440

Last change on this file since 5440 was 5440, checked in by nmedfort, 2 years ago

Large refactoring step. Removed IR generation code from Kernel (formally KernelBuilder?) and moved it into the new KernelBuilder? class.

File size: 6.0 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 PabloBlock; }
23namespace pablo { class PabloKernel; }
24namespace pablo { class Statement; }
25namespace kernel { class KernelBuilder; }
26
27/*
28 * Carry Data Manager.
29 *
30 * Each PabloBlock (Main, If, While) has a contiguous data area for carry information.
31 * The data area may be at a fixed or variable base offset from the base of the
32 * main function carry data area.
33 * The data area for each block consists of contiguous space for the local carries and
34 * advances of the block plus the areas of any ifs/whiles nested within the block.
35
36*/
37
38namespace pablo {
39
40class CarryManager {
41
42    enum { LONG_ADVANCE_BASE = 64 };
43
44public:
45 
46    CarryManager() noexcept;
47
48    void initializeCarryData(const std::unique_ptr<kernel::KernelBuilder> &  iBuilder, PabloKernel * const kernel);
49
50    void initializeCodeGen(const std::unique_ptr<kernel::KernelBuilder> &  iBuilder);
51
52    void finalizeCodeGen(const std::unique_ptr<kernel::KernelBuilder> &  iBuilder);
53
54    /* Entering and leaving loops. */
55
56    void enterLoopScope(const std::unique_ptr<kernel::KernelBuilder> &  iBuilder, const PabloBlock * const scope);
57
58    void enterLoopBody(const std::unique_ptr<kernel::KernelBuilder> &  iBuilder, llvm::BasicBlock * const entryBlock);
59
60    void leaveLoopBody(const std::unique_ptr<kernel::KernelBuilder> &  iBuilder, llvm::BasicBlock * const exitBlock);
61
62    void leaveLoopScope(const std::unique_ptr<kernel::KernelBuilder> &  iBuilder, llvm::BasicBlock * const entryBlock, llvm::BasicBlock * const exitBlock);
63
64    /* Entering and leaving ifs. */
65
66    void enterIfScope(const std::unique_ptr<kernel::KernelBuilder> &  iBuilder, const PabloBlock * const scope);
67
68    void enterIfBody(const std::unique_ptr<kernel::KernelBuilder> &  iBuilder, llvm::BasicBlock * const entryBlock);
69
70    void leaveIfBody(const std::unique_ptr<kernel::KernelBuilder> &  iBuilder, llvm::BasicBlock * const exitBlock);
71
72    void leaveIfScope(const std::unique_ptr<kernel::KernelBuilder> &  iBuilder, llvm::BasicBlock * const entryBlock, llvm::BasicBlock * const exitBlock);
73
74    /* Methods for processing individual carry-generating operations. */
75   
76    llvm::Value * addCarryInCarryOut(const std::unique_ptr<kernel::KernelBuilder> &  iBuilder, const Statement * operation, llvm::Value * const e1, llvm::Value * const e2);
77
78    llvm::Value * advanceCarryInCarryOut(const std::unique_ptr<kernel::KernelBuilder> &  iBuilder, const Advance * advance, llvm::Value * const strm);
79 
80    /* Methods for getting and setting carry summary values for If statements */
81         
82    llvm::Value * generateSummaryTest(const std::unique_ptr<kernel::KernelBuilder> &  iBuilder, llvm::Value * condition);
83
84protected:
85
86    static unsigned getScopeCount(const PabloBlock * const scope, unsigned index = 0);
87
88    static bool hasIterationSpecificAssignment(const PabloBlock * const scope);
89
90    llvm::StructType * analyse(const std::unique_ptr<kernel::KernelBuilder> &  iBuilder, const PabloBlock * const scope, const unsigned ifDepth = 0, const unsigned whileDepth = 0, const bool isNestedWithinNonCarryCollapsingLoop = false);
91
92    /* Entering and leaving scopes. */
93    void enterScope(const std::unique_ptr<kernel::KernelBuilder> &  iBuilder, const PabloBlock * const scope);
94    void leaveScope(const std::unique_ptr<kernel::KernelBuilder> &  iBuilder);
95
96    /* Methods for processing individual carry-generating operations. */
97    llvm::Value * getNextCarryIn(const std::unique_ptr<kernel::KernelBuilder> &  iBuilder);
98    void setNextCarryOut(const std::unique_ptr<kernel::KernelBuilder> &  iBuilder, llvm::Value * const carryOut);
99    llvm::Value * longAdvanceCarryInCarryOut(const std::unique_ptr<kernel::KernelBuilder> &  iBuilder, llvm::Value * const value, const unsigned shiftAmount);
100    llvm::Value * readCarryInSummary(const std::unique_ptr<kernel::KernelBuilder> &  iBuilder, llvm::ConstantInt *index) const;
101    void writeCarryOutSummary(const std::unique_ptr<kernel::KernelBuilder> &  iBuilder, llvm::Value * const summary, llvm::ConstantInt * index) const;
102
103    /* Summary handling routines */
104    void addToCarryOutSummary(const std::unique_ptr<kernel::KernelBuilder> &  iBuilder, llvm::Value * const value);
105
106private:
107
108    const PabloKernel *                             mKernel;
109
110    llvm::Value *                                   mCurrentFrame;
111    unsigned                                        mCurrentFrameIndex;
112
113    const PabloBlock *                              mCurrentScope;
114    CarryData *                                     mCarryInfo;
115
116    llvm::Value *                                   mNextSummaryTest;
117
118    unsigned                                        mIfDepth;
119
120    bool                                            mHasLongAdvance;
121
122    bool                                            mHasLoop;
123    unsigned                                        mLoopDepth;
124    llvm::Value *                                   mLoopSelector;   
125    llvm::Value *                                   mNextLoopSelector;
126    llvm::Value *                                   mCarryPackPtr;
127    std::vector<llvm::PHINode *>                    mLoopIndicies;
128
129    std::vector<CarryData>                          mCarryMetadata;
130
131    std::vector<std::pair<llvm::Value *, unsigned>> mCarryFrameStack;
132
133    unsigned                                        mCarryScopes;
134    std::vector<unsigned>                           mCarryScopeIndex;
135
136    std::vector<llvm::Value *>                      mCarrySummaryStack;
137};
138
139}
140
141#endif // CARRY_MANAGER_H
Note: See TracBrowser for help on using the repository browser.