[TOC]
- Representing output resulting from an target
OpGraphOp - It can be used as input by multiple
OpGraphOpother than targetOpGraphOp
Key members:
| Decl | usage |
|---|---|
OpGraphOp* input; |
pointer to the target OpGraphOp that output to it |
std::vector<OpGraphOp*> output; |
pointing to OpGraphOps that use it as input |
std::vector<unsigned int> output_operand; |
Is n'th operand of the OpGraphOp in OpGraphVal::outputs |
- Representing certain operation cell (e.g add operation), constant or input parameter operations
- It can use zero or multiple
OpGraphValas inputs and always create 1OpGraphValas output
Key members:
| Decl | usage |
|---|---|
std::vector<OpGraphVal*> input; |
pointing to OpGraphVals as the input operand it uses |
OpGraphVal* output; |
pointing to an OpGraphVal that it output to |
Container of OpGraphOp and OpGraphVal
Key members:
| Decl | usage |
|---|---|
std::vector<OpGraphOp*> op_nodes; |
Listing all the OpGraphOps |
std::vector<OpGraphVal*> val_nodes; |
Listing all the OpGraphVals |
std::vector<OpGraphOp*> inputs; |
All the OpGraphOps used to get values outside of the loop |
std::vector<OpGraphOp*> outputs; |
All the OpGraphOps used to output values that written in the loop, but not used in the loop |
- Will only convert instructions inside a loop
- Number of block contained in the loop must be 1
- No sub loops inside the loop
In summary, the algorithm will only handle one basic block inside the loop.
- Loop over the target block, for each instruction in the block:
- If is not cast instruction, create
OpGraphValas the output of the instruction - Fill in
std::map<Instruction*, OpGraphVal*> vals;map, which is a mapping from instruction to the correspondingOpGraphVal - If is cast instruction:
- Find the casted instruction
- Find the corresponding
OpGraphValfrom the map in step-1-2 - Fill in the map with pair of cast instruction and the
OpGraphValfound in step 1-3-2
- If is not cast instruction, create
- Loop over the target block second time, for each instruction in the block:
- If is
GetElementPtr:- Transfer to
$base+\sum_{i=1}^n offset_i$ , where$offset_i=step\times width$ by generating add and multiplication ops - Create new
OpGraphValfor instruction, replace corresponding value in map crated in step 1-2
- Transfer to
- Skip
Cast,Br,Callinstruction - For all other instruction:
- Create
OpGraphOp$op$ corresponding to instruction's opcode - Find instruction's
OpGraphVal$v$ by map in step 1-2 - Set
$op\text{->output}=v, v\text{->input}=op$ - For each operand
$o$ used in the instruction:- If operand is not instruction, then operand can only be const or input argument:
- Create new
OpGraphOp$op_2$ as "const"/"input" - Create new
OpGraphVal$v_2$ as val of previous op - Set
$op_2\text{->output}=v_2, v_2\text{->input}=op_2$ - Add
$v_2$ to$op$ 's inputs,$op$ to$v_2$ 's outputs
- Create new
- Else if is instruction:
- If instruction inside the loop:
- Find instruction represent by
$o$ by map in step 1-2, donate$v_3$ - Add
$v_3$ to$op$ 's inputs,$op$ to$v_3$ 's outputs
- Find instruction represent by
- Else if not in the loop:
- Create new
OpGraphOp$op_2$ as "input" - Create new
OpGraphVal$v_2$ as val of previous op - Set
$op_2\text{->output}=v_2, v_2\text{->input}=op_2$ - Add
$v_2$ to$op$ 's inputs,$op$ to$v_2$ 's outputs - Add
$op_2$ to OpGraph::inputs
- Create new
- If instruction inside the loop:
- If operand is not instruction, then operand can only be const or input argument:
- If instruction used outside of the target block:
- Create new
OpGraphOp$op_2$ as "output" - Set $op_2\text{->inputs}=v,
$v\text{->outputs}=op_2$ - Add
$op_2$ to OpGraph::outputs
- Create new
- Create
- If is
In limitation the target loop will contain only one basic block, thus phi can only be created by variables defined outside of the loop, and written in the loop.
Those variables has an initial value when first step into the loop ("const" or "input"), and take the result from in-loop instruction in the later loops
For each phi node
- Find the only in-loop instruction operand of
$phi$ , donate$I$ , which is anOpGraphVal - Erase
$\phi$ from$I\text{->output}$ and add$\phi\text{->output->output}$ into$I\text{->output}$ - Erase all
OpGraphOpthat output only to$\phi$ - Erase all
OpGraphValresult from previous step - Erase
$phi\text{->output}$ then erase$\phi$
Step 3 & 4 will not erase OpGraphOp result from in-loop instruction.
According to Assumption there is only one operand of
After step 2,
Remove OpGraphOps that OpGraphOp::output->output has a size of 0.
This indicating that the result value of the OpGraphOp has no further use for the program.
For target OpGraphOp
- Remove
$op$ from allOpGraphVal::output - Remove
$op\text{->output}$ - Take care of
OpGraph::inputslist - Erase
$op$
- In
./llvm-passes/DFG/DFGGeneration.cpp:472~490the base address is not added - One
OpGraphValmay be used twice inOpGraphOp(e,gadd x, x) However theOpGraphOp::output_operand" provide only one slot for eachOpGraphOp.