summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
diff options
context:
space:
mode:
authorDale Johannesen <dalej@apple.com>2008-09-17 21:13:11 +0000
committerDale Johannesen <dalej@apple.com>2008-09-17 21:13:11 +0000
commitf8610ebebc3e70a7a398dc538ee068e64d081d3b (patch)
tree16435b7d8de7d783997f521da1ab2bd2d29843a9 /llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
parentd34d6dc458a9a5bc7f0de01c4cae880424125bf9 (diff)
downloadbcm5719-llvm-f8610ebebc3e70a7a398dc538ee068e64d081d3b.tar.gz
bcm5719-llvm-f8610ebebc3e70a7a398dc538ee068e64d081d3b.zip
Add a bit to mark operands of asm's that conflict
with an earlyclobber operand elsewhere. Propagate this bit and the earlyclobber bit through SDISel. Change linear-scan RA not to allocate regs in a way that conflicts with an earlyclobber. See also comments. llvm-svn: 56290
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp36
1 files changed, 23 insertions, 13 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
index 62a6b4f1808..9492b33527f 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
@@ -4909,8 +4909,10 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
assert(OpInfo.isIndirect && "Memory output must be indirect operand");
// Add information to the INLINEASM node to know about this output.
- unsigned ResOpType = 4/*MEM*/ | (1 << 3);
- AsmNodeOperands.push_back(DAG.getTargetConstant(ResOpType,
+ unsigned ResOpType = SawEarlyClobber ?
+ 7 /* MEM OVERLAPS EARLYCLOBBER */ :
+ 4/*MEM*/;
+ AsmNodeOperands.push_back(DAG.getTargetConstant(ResOpType | (1<<3),
TLI.getPointerTy()));
AsmNodeOperands.push_back(OpInfo.CallOperand);
break;
@@ -4963,7 +4965,8 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
cast<ConstantSDNode>(AsmNodeOperands[CurOp])->getZExtValue();
assert(((NumOps & 7) == 2 /*REGDEF*/ ||
(NumOps & 7) == 6 /*EARLYCLOBBER REGDEF*/ ||
- (NumOps & 7) == 4 /*MEM*/) &&
+ (NumOps & 7) == 4 /*MEM*/ ||
+ (NumOps & 7) == 7 /*MEM OVERLAPS EARLYCLOBBER*/) &&
"Skipped past definitions?");
CurOp += (NumOps>>3)+1;
}
@@ -4985,14 +4988,17 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
// Use the produced MatchedRegs object to
MatchedRegs.getCopyToRegs(InOperandVal, DAG, Chain, &Flag);
- MatchedRegs.AddInlineAsmOperands(1 /*REGUSE*/, DAG, AsmNodeOperands);
+ MatchedRegs.AddInlineAsmOperands(SawEarlyClobber ?
+ 1 /*REGUSE*/ :
+ 5 /*REGUSE OVERLAPS EARLYCLOBBER*/,
+ DAG, AsmNodeOperands);
break;
} else {
- assert((NumOps & 7) == 4/*MEM*/ && "Unknown matching constraint!");
+ assert(((NumOps & 7) == 7/*MEM OVERLAPS EARLYCLOBBER */ ||
+ (NumOps & 7) == 4) && "Unknown matching constraint!");
assert((NumOps >> 3) == 1 && "Unexpected number of operands");
// Add information to the INLINEASM node to know about this input.
- unsigned ResOpType = 4/*MEM*/ | (1 << 3);
- AsmNodeOperands.push_back(DAG.getTargetConstant(ResOpType,
+ AsmNodeOperands.push_back(DAG.getTargetConstant(NumOps,
TLI.getPointerTy()));
AsmNodeOperands.push_back(AsmNodeOperands[CurOp+1]);
break;
@@ -5024,8 +5030,10 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
"Memory operands expect pointer values");
// Add information to the INLINEASM node to know about this input.
- unsigned ResOpType = 4/*MEM*/ | (1 << 3);
- AsmNodeOperands.push_back(DAG.getTargetConstant(ResOpType,
+ unsigned ResOpType = SawEarlyClobber ?
+ 7 /* MEM OVERLAPS EARLYCLOBBER */ :
+ 4/*MEM*/;
+ AsmNodeOperands.push_back(DAG.getTargetConstant(ResOpType | (1<<3),
TLI.getPointerTy()));
AsmNodeOperands.push_back(InOperandVal);
break;
@@ -5043,16 +5051,18 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
OpInfo.AssignedRegs.getCopyToRegs(InOperandVal, DAG, Chain, &Flag);
- OpInfo.AssignedRegs.AddInlineAsmOperands(1/*REGUSE*/, DAG,
- AsmNodeOperands);
+ OpInfo.AssignedRegs.AddInlineAsmOperands(SawEarlyClobber ?
+ 5 /*REGUSE OVERLAPS EARLYCLOBBER*/:
+ 1/*REGUSE*/,
+ DAG, AsmNodeOperands);
break;
}
case InlineAsm::isClobber: {
// 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(2/*REGDEF*/, DAG,
- AsmNodeOperands);
+ OpInfo.AssignedRegs.AddInlineAsmOperands(6 /* EARLYCLOBBER REGDEF */,
+ DAG, AsmNodeOperands);
break;
}
}
OpenPOWER on IntegriCloud