mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
Generate tree nodes for Phi instructions.
llvm-svn: 337
This commit is contained in:
parent
46dd49a011
commit
5dcec96655
@ -227,8 +227,7 @@ InstrForest::buildTreesForMethod(Method *method)
|
|||||||
++instrIter)
|
++instrIter)
|
||||||
{
|
{
|
||||||
Instruction *instr = *instrIter;
|
Instruction *instr = *instrIter;
|
||||||
if (! instr->isPHINode())
|
(void) this->buildTreeForInstruction(instr);
|
||||||
(void) this->buildTreeForInstruction(instr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -291,15 +290,13 @@ InstrForest::buildTreeForInstruction(Instruction* instr)
|
|||||||
this->noteTreeNodeForInstr(instr, treeNode);
|
this->noteTreeNodeForInstr(instr, treeNode);
|
||||||
|
|
||||||
// If the instruction has more than 2 instruction operands,
|
// If the instruction has more than 2 instruction operands,
|
||||||
// then we will not add any children. This assumes that instructions
|
// then we need to create artificial list nodes to hold them.
|
||||||
// like 'call' that have more than 2 instruction operands do not
|
// (Note that we only not count operands that get tree nodes, and not
|
||||||
// ever get combined with the instructions that compute the operands.
|
// others such as branch labels for a branch or switch instruction.)
|
||||||
// Note that we only count operands of type instruction and not other
|
|
||||||
// values such as branch labels for a branch or switch instruction.
|
|
||||||
//
|
//
|
||||||
// To do this efficiently, we'll walk all operands, build treeNodes
|
// To do this efficiently, we'll walk all operands, build treeNodes
|
||||||
// for all instruction operands and save them in an array, and then
|
// for all appropriate operands and save them in an array. We then
|
||||||
// insert children at the end if there are not more than 2.
|
// insert children at the end, creating list nodes where needed.
|
||||||
// As a performance optimization, allocate a child array only
|
// As a performance optimization, allocate a child array only
|
||||||
// if a fixed array is too small.
|
// if a fixed array is too small.
|
||||||
//
|
//
|
||||||
@ -314,11 +311,9 @@ InstrForest::buildTreeForInstruction(Instruction* instr)
|
|||||||
//
|
//
|
||||||
// Walk the operands of the instruction
|
// Walk the operands of the instruction
|
||||||
//
|
//
|
||||||
for (Instruction::op_iterator opIter = instr->op_begin();
|
for (Instruction::op_iterator O=instr->op_begin(); O != instr->op_end(); ++O)
|
||||||
opIter != instr->op_end();
|
|
||||||
++opIter)
|
|
||||||
{
|
{
|
||||||
Value* operand = *opIter;
|
Value* operand = *O;
|
||||||
|
|
||||||
// Check if the operand is a data value, not an branch label, type,
|
// Check if the operand is a data value, not an branch label, type,
|
||||||
// method or module. If the operand is an address type (i.e., label
|
// method or module. If the operand is an address type (i.e., label
|
||||||
@ -331,18 +326,16 @@ InstrForest::buildTreeForInstruction(Instruction* instr)
|
|||||||
|| operand->getValueType() == Value::MethodVal)
|
|| operand->getValueType() == Value::MethodVal)
|
||||||
&& ! instr->isTerminator());
|
&& ! instr->isTerminator());
|
||||||
|
|
||||||
if (/* (*opIter) != NULL
|
if ( includeAddressOperand
|
||||||
&&*/ includeAddressOperand
|
|| operand->getValueType() == Value::InstructionVal
|
||||||
|| operand->getValueType() == Value::InstructionVal
|
|| operand->getValueType() == Value::ConstantVal
|
||||||
|| operand->getValueType() == Value::ConstantVal
|
|| operand->getValueType() == Value::MethodArgumentVal)
|
||||||
|| operand->getValueType() == Value::MethodArgumentVal)
|
|
||||||
{// This operand is a data value
|
{// This operand is a data value
|
||||||
|
|
||||||
// An instruction that computes the incoming value is added as a
|
// An instruction that computes the incoming value is added as a
|
||||||
// child of the current instruction if:
|
// child of the current instruction if:
|
||||||
// the value has only a single use
|
// the value has only a single use
|
||||||
// AND both instructions are in the same basic block
|
// AND both instructions are in the same basic block.
|
||||||
// AND the instruction is not a PHI
|
|
||||||
//
|
//
|
||||||
// (Note that if the value has only a single use (viz., `instr'),
|
// (Note that if the value has only a single use (viz., `instr'),
|
||||||
// the def of the value can be safely moved just before instr
|
// the def of the value can be safely moved just before instr
|
||||||
@ -354,8 +347,7 @@ InstrForest::buildTreeForInstruction(Instruction* instr)
|
|||||||
InstrTreeNode* opTreeNode;
|
InstrTreeNode* opTreeNode;
|
||||||
if (operand->getValueType() == Value::InstructionVal
|
if (operand->getValueType() == Value::InstructionVal
|
||||||
&& operand->use_size() == 1
|
&& operand->use_size() == 1
|
||||||
&& ((Instruction*)operand)->getParent() == instr->getParent()
|
&& ((Instruction*)operand)->getParent() == instr->getParent())
|
||||||
&& ! ((Instruction*)operand)->isPHINode())
|
|
||||||
{
|
{
|
||||||
// Recursively create a treeNode for it.
|
// Recursively create a treeNode for it.
|
||||||
opTreeNode =this->buildTreeForInstruction((Instruction*)operand);
|
opTreeNode =this->buildTreeForInstruction((Instruction*)operand);
|
||||||
@ -391,7 +383,8 @@ InstrForest::buildTreeForInstruction(Instruction* instr)
|
|||||||
if (numChildren > 2)
|
if (numChildren > 2)
|
||||||
{
|
{
|
||||||
unsigned instrOpcode = treeNode->getInstruction()->getOpcode();
|
unsigned instrOpcode = treeNode->getInstruction()->getOpcode();
|
||||||
assert(instrOpcode == Instruction::Call ||
|
assert(instrOpcode == Instruction::PHINode ||
|
||||||
|
instrOpcode == Instruction::Call ||
|
||||||
instrOpcode == Instruction::Load ||
|
instrOpcode == Instruction::Load ||
|
||||||
instrOpcode == Instruction::Store ||
|
instrOpcode == Instruction::Store ||
|
||||||
instrOpcode == Instruction::GetElementPtr);
|
instrOpcode == Instruction::GetElementPtr);
|
||||||
|
Loading…
Reference in New Issue
Block a user