1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +01:00

Fix an issue where a use might be selected before a def, and then we didn't respect the pre-chosen vreg

assignment when selecting the def.  This is the naive solution to the problem: insert a copy to the pre-chosen
vreg.  Other solutions might be preferable, such as:
  1) Passing the dest reg into FastEmit_.  However, this would require the higher level code to know about reg classes, which they don't currently.
  2) Selecting blocks in reverse postorder.  This has some compile time cost for computing the order, and we'd need to measure its impact.

llvm-svn: 55555
This commit is contained in:
Owen Anderson 2008-08-30 00:38:46 +00:00
parent 1cfbb25e75
commit 6c8f04643e
2 changed files with 26 additions and 8 deletions

View File

@ -225,6 +225,9 @@ private:
bool SelectCast(Instruction *I, ISD::NodeType Opcode, bool SelectCast(Instruction *I, ISD::NodeType Opcode,
DenseMap<const Value*, unsigned> &ValueMap); DenseMap<const Value*, unsigned> &ValueMap);
void UpdateValueMap(Instruction* I, unsigned Reg,
DenseMap<const Value*, unsigned> &ValueMap);
}; };
} }

View File

@ -63,6 +63,21 @@ unsigned FastISel::getRegForValue(Value *V, DenseMap<const Value*, unsigned> &Va
return Reg; return Reg;
} }
/// UpdateValueMap - Update the value map to include the new mapping for this
/// instruction, or insert an extra copy to get the result in a previous
/// determined register.
/// NOTE: This is only necessary because we might select a block that uses
/// a value before we select the block that defines the value. It might be
/// possible to fix this by selecting blocks in reverse postorder.
void FastISel::UpdateValueMap(Instruction* I, unsigned Reg,
DenseMap<const Value*, unsigned> &ValueMap) {
if (!ValueMap.count(I))
ValueMap[I] = Reg;
else
TII.copyRegToReg(*MBB, MBB->end(), ValueMap[I],
Reg, MRI.getRegClass(Reg), MRI.getRegClass(Reg));
}
/// SelectBinaryOp - Select and emit code for a binary operator instruction, /// SelectBinaryOp - Select and emit code for a binary operator instruction,
/// which has an opcode which directly corresponds to the given ISD opcode. /// which has an opcode which directly corresponds to the given ISD opcode.
/// ///
@ -90,7 +105,7 @@ bool FastISel::SelectBinaryOp(Instruction *I, ISD::NodeType ISDOpcode,
ISDOpcode, Op0, CI->getZExtValue()); ISDOpcode, Op0, CI->getZExtValue());
if (ResultReg != 0) { if (ResultReg != 0) {
// We successfully emitted code for the given LLVM Instruction. // We successfully emitted code for the given LLVM Instruction.
ValueMap[I] = ResultReg; UpdateValueMap(I, ResultReg, ValueMap);
return true; return true;
} }
} }
@ -101,7 +116,7 @@ bool FastISel::SelectBinaryOp(Instruction *I, ISD::NodeType ISDOpcode,
ISDOpcode, Op0, CF); ISDOpcode, Op0, CF);
if (ResultReg != 0) { if (ResultReg != 0) {
// We successfully emitted code for the given LLVM Instruction. // We successfully emitted code for the given LLVM Instruction.
ValueMap[I] = ResultReg; UpdateValueMap(I, ResultReg, ValueMap);
return true; return true;
} }
} }
@ -120,7 +135,7 @@ bool FastISel::SelectBinaryOp(Instruction *I, ISD::NodeType ISDOpcode,
return false; return false;
// We successfully emitted code for the given LLVM Instruction. // We successfully emitted code for the given LLVM Instruction.
ValueMap[I] = ResultReg; UpdateValueMap(I, ResultReg, ValueMap);
return true; return true;
} }
@ -196,7 +211,7 @@ bool FastISel::SelectGetElementPtr(Instruction *I,
} }
// We successfully emitted code for the given LLVM Instruction. // We successfully emitted code for the given LLVM Instruction.
ValueMap[I] = N; UpdateValueMap(I, N, ValueMap);
return true; return true;
} }
@ -223,7 +238,7 @@ bool FastISel::SelectCast(Instruction *I, ISD::NodeType Opcode,
if (!ResultReg) if (!ResultReg)
return false; return false;
ValueMap[I] = ResultReg; UpdateValueMap(I, ResultReg, ValueMap);
return true; return true;
} }
@ -234,7 +249,7 @@ bool FastISel::SelectBitCast(Instruction *I,
unsigned Reg = getRegForValue(I->getOperand(0), ValueMap); unsigned Reg = getRegForValue(I->getOperand(0), ValueMap);
if (Reg == 0) if (Reg == 0)
return false; return false;
ValueMap[I] = Reg; UpdateValueMap(I, Reg, ValueMap);
return true; return true;
} }
@ -274,7 +289,7 @@ bool FastISel::SelectBitCast(Instruction *I,
if (!ResultReg) if (!ResultReg)
return false; return false;
ValueMap[I] = ResultReg; UpdateValueMap(I, ResultReg, ValueMap);
return true; return true;
} }
@ -384,7 +399,7 @@ FastISel::SelectInstructions(BasicBlock::iterator Begin,
MVT DstVT = TLI.getValueType(I->getType()); MVT DstVT = TLI.getValueType(I->getType());
if (SrcVT.getSimpleVT() == DstVT.getSimpleVT()) { if (SrcVT.getSimpleVT() == DstVT.getSimpleVT()) {
if (ValueMap[I->getOperand(0)]) { if (ValueMap[I->getOperand(0)]) {
ValueMap[I] = ValueMap[I->getOperand(0)]; UpdateValueMap(I, ValueMap[I->getOperand(0)], ValueMap);
break; break;
} else } else
// Unhandled operand // Unhandled operand