1
0
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:
Vikram S. Adve 2001-07-31 21:49:53 +00:00
parent 46dd49a011
commit 5dcec96655

View File

@ -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);