aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2011-06-27 04:08:33 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2011-06-27 04:08:33 +0000
commitf792fa90f1125553008659c743cba85b9b5d2e5e (patch)
tree55af9377e3bfb8833d0c5f862a6a19f7cd5fb39f
parent7a2ecd3f99ae4dede7e8c1984c2a08984be69363 (diff)
downloadexternal_llvm-f792fa90f1125553008659c743cba85b9b5d2e5e.zip
external_llvm-f792fa90f1125553008659c743cba85b9b5d2e5e.tar.gz
external_llvm-f792fa90f1125553008659c743cba85b9b5d2e5e.tar.bz2
Distinguish early clobber output operands from clobbered registers.
Both become <earlyclobber> defs on the INLINEASM MachineInstr, but we now use two different asm operand kinds. The new Kind_Clobber is treated identically to the old Kind_RegDefEarlyClobber for now, but x87 floating point stack inline assembly does care about the difference. This will pop a register off the stack: asm("fstp %st" : : "t"(x) : "st"); While this will pop the input and push an output: asm("fst %st" : "=&t"(r) : "t"(x)); We need to know if ST0 was a clobber or an output operand, and we can't depend on <dead> flags for that. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@133902 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/InlineAsm.h26
-rw-r--r--lib/CodeGen/MachineInstr.cpp3
-rw-r--r--lib/CodeGen/SelectionDAG/InstrEmitter.cpp1
-rw-r--r--lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp3
-rw-r--r--lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp3
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp3
6 files changed, 26 insertions, 13 deletions
diff --git a/include/llvm/InlineAsm.h b/include/llvm/InlineAsm.h
index 0d86086..ed5bf8b 100644
--- a/include/llvm/InlineAsm.h
+++ b/include/llvm/InlineAsm.h
@@ -188,25 +188,32 @@ public:
// in the backend.
enum {
+ // Fixed operands on an INLINEASM SDNode.
Op_InputChain = 0,
Op_AsmString = 1,
Op_MDNode = 2,
Op_ExtraInfo = 3, // HasSideEffects, IsAlignStack
Op_FirstOperand = 4,
+ // Fixed operands on an INLINEASM MachineInstr.
MIOp_AsmString = 0,
MIOp_ExtraInfo = 1, // HasSideEffects, IsAlignStack
MIOp_FirstOperand = 2,
+ // Interpretation of the MIOp_ExtraInfo bit field.
Extra_HasSideEffects = 1,
Extra_IsAlignStack = 2,
-
- Kind_RegUse = 1,
- Kind_RegDef = 2,
- Kind_Imm = 3,
- Kind_Mem = 4,
- Kind_RegDefEarlyClobber = 6,
-
+
+ // Inline asm operands map to multiple SDNode / MachineInstr operands.
+ // The first operand is an immediate describing the asm operand, the low
+ // bits is the kind:
+ Kind_RegUse = 1, // Input register, "r".
+ Kind_RegDef = 2, // Output register, "=r".
+ Kind_RegDefEarlyClobber = 3, // Early-clobber output register, "=&r".
+ Kind_Clobber = 4, // Clobbered register, "~r".
+ Kind_Imm = 5, // Immediate.
+ Kind_Mem = 6, // Memory operand, "m".
+
Flag_MatchingOperand = 0x80000000
};
@@ -233,7 +240,10 @@ public:
static bool isRegDefEarlyClobberKind(unsigned Flag) {
return getKind(Flag) == Kind_RegDefEarlyClobber;
}
-
+ static bool isClobberKind(unsigned Flag) {
+ return getKind(Flag) == Kind_Clobber;
+ }
+
/// getNumOperandRegisters - Extract the number of registers field from the
/// inline asm operand flag.
static unsigned getNumOperandRegisters(unsigned Flag) {
diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp
index d4d8202..938b83d 100644
--- a/lib/CodeGen/MachineInstr.cpp
+++ b/lib/CodeGen/MachineInstr.cpp
@@ -1443,9 +1443,10 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM) const {
switch (InlineAsm::getKind(Flag)) {
case InlineAsm::Kind_RegUse: OS << ":[reguse]"; break;
case InlineAsm::Kind_RegDef: OS << ":[regdef]"; break;
+ case InlineAsm::Kind_RegDefEarlyClobber: OS << ":[regdef-ec]"; break;
+ case InlineAsm::Kind_Clobber: OS << ":[clobber]"; break;
case InlineAsm::Kind_Imm: OS << ":[imm]"; break;
case InlineAsm::Kind_Mem: OS << ":[mem]"; break;
- case InlineAsm::Kind_RegDefEarlyClobber: OS << ":[regdef-ec]"; break;
default: OS << ":[??" << InlineAsm::getKind(Flag) << ']'; break;
}
diff --git a/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
index 3c6a46e..e8c9c51 100644
--- a/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
+++ b/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
@@ -851,6 +851,7 @@ EmitSpecialNode(SDNode *Node, bool IsClone, bool IsCloned,
}
break;
case InlineAsm::Kind_RegDefEarlyClobber:
+ case InlineAsm::Kind_Clobber:
for (; NumVals; --NumVals, ++i) {
unsigned Reg = cast<RegisterSDNode>(Node->getOperand(i))->getReg();
MI->addOperand(MachineOperand::CreateReg(Reg, /*isDef=*/ true,
diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp
index 7b560d1..6bed1db 100644
--- a/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp
+++ b/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp
@@ -490,7 +490,8 @@ bool ScheduleDAGFast::DelayForLiveRegsBottomUp(SUnit *SU,
++i; // Skip the ID value.
if (InlineAsm::isRegDefKind(Flags) ||
- InlineAsm::isRegDefEarlyClobberKind(Flags)) {
+ InlineAsm::isRegDefEarlyClobberKind(Flags) ||
+ InlineAsm::isClobberKind(Flags)) {
// Check for def of register or earlyclobber register.
for (; NumVals; --NumVals, ++i) {
unsigned Reg = cast<RegisterSDNode>(Node->getOperand(i))->getReg();
diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
index a827187..1053b88 100644
--- a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
+++ b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
@@ -1092,7 +1092,8 @@ DelayForLiveRegsBottomUp(SUnit *SU, SmallVector<unsigned, 4> &LRegs) {
++i; // Skip the ID value.
if (InlineAsm::isRegDefKind(Flags) ||
- InlineAsm::isRegDefEarlyClobberKind(Flags)) {
+ InlineAsm::isRegDefEarlyClobberKind(Flags) ||
+ InlineAsm::isClobberKind(Flags)) {
// Check for def of register or earlyclobber register.
for (; NumVals; --NumVals, ++i) {
unsigned Reg = cast<RegisterSDNode>(Node->getOperand(i))->getReg();
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 19bfa33..3001206 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -6051,8 +6051,7 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) {
// Add the clobbered value to the operand list, so that the register
// allocator is aware that the physreg got clobbered.
if (!OpInfo.AssignedRegs.Regs.empty())
- OpInfo.AssignedRegs.AddInlineAsmOperands(
- InlineAsm::Kind_RegDefEarlyClobber,
+ OpInfo.AssignedRegs.AddInlineAsmOperands(InlineAsm::Kind_Clobber,
false, 0, DAG,
AsmNodeOperands);
break;