hoshi-lang dev
Yet another programming language
Loading...
Searching...
No Matches
IROptimizer.hpp
Go to the documentation of this file.
1//
2// Created by Jerry Chou on 10/2/2024.
3//
4
5#ifndef IROPTIMIZER_HPP
6#define IROPTIMIZER_HPP
7#include <set>
8
9#include "IR.h"
10#include "share/def.hpp"
11
14
15namespace yoi {
16
17 class IRFunctionOptimizer;
18
19 class AnalysisState;
20
21 struct CallGraph {
22 using FuncIdentifier = std::pair<indexT, indexT>; // (module index, function index)
23
25
26 std::map<FuncIdentifier, std::set<FuncIdentifier>> callGraph; // successors for each function
27 std::map<FuncIdentifier, std::set<FuncIdentifier>> callerGraph; // predecessors for each function
28 std::set<FuncIdentifier> entryPoints; // entry points of the program
29 std::set<FuncIdentifier> unreachableFunctions; // functions that are not reachable from the entry points
30 std::set<FuncIdentifier> functions; // all functions in the program
31
32 CallGraph() = default;
33
34 void addCall(FuncIdentifier caller, FuncIdentifier callee);
35
36 void traverseGraph();
37 };
38
40 enum class ParameterState { Raw, Nullable, Plain };
41
44 bool isReturnValueRaw = true;
46 bool isYieldValueRaw = true;
47
48 // For checking if the analysis has reached a fixed point.
49 bool operator!=(const FunctionAnalysisInfo &other) const;
50 };
51
53 std::shared_ptr<compilerContext> compilerCtx;
54 std::shared_ptr<IRModule> irModule;
55 std::shared_ptr<IRFunctionDefinition> targetFunction;
57 std::map<CallGraph::FuncIdentifier, FunctionAnalysisInfo> &globalAnalysisResults;
58
59 public:
60
62 struct Item {
65 std::set<yoi::indexT> instructions;
66 bool optimizable{true};
67
69
71
73 const std::set<yoi::indexT> &instructions,
74 bool optimizable);
75
77
79
80 struct Iterator {
81 std::set<yoi::indexT>::const_iterator it;
82
83 Iterator(const std::set<yoi::indexT> &set);
84
85 Iterator(std::set<yoi::indexT>::const_iterator it);
86
87 bool operator!=(const Iterator &other) const;
88
89 yoi::indexT operator*() const;
90
92 };
93
94 Iterator begin() const;
95
96 Iterator end() const;
97 };
98 std::shared_ptr<IRValueType> type;
123
125
127 };
128 std::vector<Item> items;
129
130 SimulationStack() = default;
131
138 void push(const std::shared_ptr<IRValueType> &type,
139 const Item::ContributedInstructionSet &contributedInstructions);
140
147 void push(const std::shared_ptr<IRValueType> &type,
148 const Item::ContributedInstructionSet &contributedInstructions,
149 Item::PossibleValue value);
150
151 void push(const Item &item);
152
153 void pop();
154
155 Item &peek(yoi::indexT index);
157
164 yoi::indexT reduce(const SimulationStack::Item::ContributedInstructionSet &contributedInstructions,
165 yoi::indexT currentIndex);
166
167 SimulationStack::Item add(const IRFunctionOptimizer::SimulationStack::Item &a,
169
170 SimulationStack::Item sub(const IRFunctionOptimizer::SimulationStack::Item &a,
172
173 SimulationStack::Item mul(const IRFunctionOptimizer::SimulationStack::Item &a,
175
176 SimulationStack::Item div(const IRFunctionOptimizer::SimulationStack::Item &a,
178
179 SimulationStack::Item mod(const IRFunctionOptimizer::SimulationStack::Item &a,
181
182 SimulationStack::Item negate(const IRFunctionOptimizer::SimulationStack::Item &a);
183
184 SimulationStack::Item bitwiseNot(const IRFunctionOptimizer::SimulationStack::Item &a);
185
186 SimulationStack::Item bitwiseAnd(const IRFunctionOptimizer::SimulationStack::Item &a,
188
189 SimulationStack::Item bitwiseOr(const IRFunctionOptimizer::SimulationStack::Item &a,
191
192 SimulationStack::Item bitwiseXor(const IRFunctionOptimizer::SimulationStack::Item &a,
194
197
200
201 SimulationStack::Item lessThan(const SimulationStack::Item &item, const SimulationStack::Item &right);
202
203 SimulationStack::Item lessThanOrEqual(const SimulationStack::Item &item, const SimulationStack::Item &right);
204
205 SimulationStack::Item greaterThan(const SimulationStack::Item &item, const SimulationStack::Item &right);
206
207 SimulationStack::Item greaterThanOrEqual(const SimulationStack::Item &item, const SimulationStack::Item &right);
208
209 SimulationStack::Item equal(const SimulationStack::Item &item, const SimulationStack::Item &right);
210
211 SimulationStack::Item notEqual(const SimulationStack::Item &item, const SimulationStack::Item &right);
212
216 SimulationStack::Item possibleValue; // store the result of the latest store operation to this variable.
217 };
218
219 std::map<yoi::indexT, VariablesExtraInfo> variablesExtraInfo;
220
228
229 IRFunctionOptimizer(const std::shared_ptr<compilerContext> &compilerCtx,
230 const std::shared_ptr<IRModule> &irModule,
231 std::map<CallGraph::FuncIdentifier, FunctionAnalysisInfo> &globalResults);
232
234
235 IRFunctionOptimizer &setTargetFunction(const std::shared_ptr<IRFunctionDefinition> &targetFunction,
237
239
241
243
245
247
249
251
253
255
256 AnalysisState analyzeBlock(indexT blockIndex, const AnalysisState &inState);
257
258 void transformBlock(indexT blockIndex, const AnalysisState &inState);
259
260 std::pair<std::map<indexT, std::vector<indexT>>, std::map<indexT, std::vector<indexT>>> performCFGAnalysis();
261
263 bool performRawCheck();
266
267 private:
268 AnalysisState analyzeBlockForNullable(indexT blockIndex, const AnalysisState &inState);
269 AnalysisState analyzeBlockForRaw(indexT blockIndex, const AnalysisState &inState);
271
275 };
276
279 std::map<indexT, IRFunctionOptimizer::VariablesExtraInfo> variableStates;
280
281 // A simple comparison for the worklist algorithm to detect changes.
282 bool operator!=(const AnalysisState &other) const;
283 };
284
286
288 std::shared_ptr<compilerContext> compilerCtx;
291 std::map<CallGraph::FuncIdentifier, FunctionAnalysisInfo> functionAnalysisResults;
292
294
296
298
299 public:
300 IROptimizer(const std::shared_ptr<compilerContext> &compilerCtx, yoi::indexT entryModuleIndex);
301
302 void buildCallGraph();
303
304 void optimize();
305 };
306
307} // namespace yoi
308
309#endif // IROPTIMIZER_HPP
SimulationStack::Item lessThanOrEqual(const SimulationStack::Item &item, const SimulationStack::Item &right)
std::map< CallGraph::FuncIdentifier, FunctionAnalysisInfo > & globalAnalysisResults
AnalysisState mergeStatesForInterfaceAllocationReduction(const AnalysisState &s1, const AnalysisState &s2)
std::map< yoi::indexT, VariablesExtraInfo > variablesExtraInfo
CallGraph::FuncIdentifier currentFuncId
yoi::indexT reduce(const SimulationStack::Item::ContributedInstructionSet &contributedInstructions, yoi::indexT currentIndex)
IRFunctionOptimizer & reduceEmptyCodeBlock()
void handleInstruction(const IR &ins, yoi::indexT insIndex, yoi::indexT currentCodeBlockIndex)
SimulationStack::Item equal(const SimulationStack::Item &item, const SimulationStack::Item &right)
SimulationStack::Item div(const IRFunctionOptimizer::SimulationStack::Item &a, const IRFunctionOptimizer::SimulationStack::Item &b)
void transformBlock(indexT blockIndex, const AnalysisState &inState)
std::shared_ptr< IRFunctionDefinition > targetFunction
SimulationStack::Item add(const IRFunctionOptimizer::SimulationStack::Item &a, const IRFunctionOptimizer::SimulationStack::Item &b)
SimulationStack::Item mul(const IRFunctionOptimizer::SimulationStack::Item &a, const IRFunctionOptimizer::SimulationStack::Item &b)
SimulationStack::Item greaterThanOrEqual(const SimulationStack::Item &item, const SimulationStack::Item &right)
SimulationStack::Item sub(const IRFunctionOptimizer::SimulationStack::Item &a, const IRFunctionOptimizer::SimulationStack::Item &b)
AnalysisState analyzeBlockForRaw(indexT blockIndex, const AnalysisState &inState)
SimulationStack::Item bitwiseAnd(const IRFunctionOptimizer::SimulationStack::Item &a, const IRFunctionOptimizer::SimulationStack::Item &b)
IRFunctionOptimizer & controlFlowOptimization()
struct yoi::IRFunctionOptimizer::SimulationStack simulationStack
SimulationStack::Item negate(const IRFunctionOptimizer::SimulationStack::Item &a)
SimulationStack::Item bitwiseShiftRight(const IRFunctionOptimizer::SimulationStack::Item &a, const IRFunctionOptimizer::SimulationStack::Item &b)
IRFunctionOptimizer & doOptimizationForCurrentFunction()
SimulationStack::Item bitwiseNot(const IRFunctionOptimizer::SimulationStack::Item &a)
yoi::indexT currentCodeBlockIndex
std::pair< std::map< indexT, std::vector< indexT > >, std::map< indexT, std::vector< indexT > > > performCFGAnalysis()
AnalysisState mergeStatesForRaw(const AnalysisState &s1, const AnalysisState &s2)
IRFunctionOptimizer & reduceRedundantTempVar()
IRFunctionOptimizer & reduceRedundantNop()
SimulationStack::Item mod(const IRFunctionOptimizer::SimulationStack::Item &a, const IRFunctionOptimizer::SimulationStack::Item &b)
yoi::indexT generatePushOp(const SimulationStack::Item &item, yoi::indexT index)
SimulationStack::Item bitwiseShiftLeft(const IRFunctionOptimizer::SimulationStack::Item &a, const IRFunctionOptimizer::SimulationStack::Item &b)
AnalysisState analyzeBlockForNullable(indexT blockIndex, const AnalysisState &inState)
AnalysisState analyzeBlock(indexT blockIndex, const AnalysisState &inState)
IRFunctionOptimizer & reduceRedundantJump()
SimulationStack::Item lessThan(const SimulationStack::Item &item, const SimulationStack::Item &right)
IRFunctionOptimizer & reduceRedundantCodeAfterRet()
AnalysisState analyzeBlockForInterfaceAllocationReduction(indexT blockIndex, const AnalysisState &inState)
IRFunctionOptimizer & reduceRedundantConstantExpr()
IRFunctionOptimizer & setTargetFunction(const std::shared_ptr< IRFunctionDefinition > &targetFunction, CallGraph::FuncIdentifier funcId)
SimulationStack::Item bitwiseOr(const IRFunctionOptimizer::SimulationStack::Item &a, const IRFunctionOptimizer::SimulationStack::Item &b)
AnalysisState mergeStatesForNullable(const AnalysisState &s1, const AnalysisState &s2)
std::shared_ptr< IRModule > irModule
std::shared_ptr< compilerContext > compilerCtx
SimulationStack::Item notEqual(const SimulationStack::Item &item, const SimulationStack::Item &right)
SimulationStack::Item bitwiseXor(const IRFunctionOptimizer::SimulationStack::Item &a, const IRFunctionOptimizer::SimulationStack::Item &b)
SimulationStack::Item greaterThan(const SimulationStack::Item &item, const SimulationStack::Item &right)
bool performInterfaceWrapperPass()
bool performStructNullablePass()
bool performBaseOptimization()
yoi::indexT entryModuleIndex
std::shared_ptr< compilerContext > compilerCtx
std::map< CallGraph::FuncIdentifier, FunctionAnalysisInfo > functionAnalysisResults
Definition IR.h:264
std::vector< t > vec
Definition def.hpp:53
uint64_t indexT
Definition def.hpp:51
AnalysisState mergeStates(const AnalysisState &s1, const AnalysisState &s2)
IRFunctionOptimizer::SimulationStack stack
std::map< indexT, IRFunctionOptimizer::VariablesExtraInfo > variableStates
bool operator!=(const AnalysisState &other) const
std::map< FuncIdentifier, std::set< FuncIdentifier > > callGraph
CallGraph()=default
std::pair< indexT, indexT > FuncIdentifier
void addCall(FuncIdentifier caller, FuncIdentifier callee)
std::set< FuncIdentifier > functions
yoi::indexT entryModuleIndex
std::set< FuncIdentifier > entryPoints
std::map< FuncIdentifier, std::set< FuncIdentifier > > callerGraph
std::set< FuncIdentifier > unreachableFunctions
yoi::vec< ParameterState > paramStates
bool operator!=(const FunctionAnalysisInfo &other) const
ContributedInstructionSet operator+(const ContributedInstructionSet &other) const
union yoi::IRFunctionOptimizer::SimulationStack::Item::PossibleValue possibleValue
void push(const std::shared_ptr< IRValueType > &type, const Item::ContributedInstructionSet &contributedInstructions)