Hi Arnold,
Thanks! Some comments.
+static bool IsPossiblyOverwrittenArgumentOfTailCall(SDOperand Op,
+ MachineFrameInfo * MFI) {
RegisterSDNode * OpReg = NULL;
+ FrameIndexSDNode * FrameIdxNode = NULL;
+ int FrameIdx = 0;
if (Op.getOpcode() == ISD::FORMAL_ARGUMENTS ||
(Op.getOpcode()== ISD::CopyFromReg &&
- (OpReg = cast<RegisterSDNode>(Op.getOperand(1))) &&
- OpReg->getReg() >= TargetRegisterInfo::FirstVirtualRegister))
+ (OpReg = dyn_cast<RegisterSDNode>(Op.getOperand(1))) &&
+ (OpReg->getReg() >= TargetRegisterInfo::FirstVirtualRegister))
+ (Op.getOpcode() == ISD::LOAD &&
+ (FrameIdxNode = dyn_cast<FrameIndexSDNode>(Op.getOperand(1))) &&
+ ((FrameIdx = FrameIdxNode->getIndex()) < 0) &&
+ (MFI->getObjectOffset(FrameIdx) >= 0)))
Instead of assuming negative frame index has some special meaning, perhaps use isImmutableObjectIndex()?
+ int NewReturnAddrFI;
if (IsTailCall) {
// Adjust the Return address stack slot.
if (FPDiff) {
@@ -1453,7 +1462,7 @@
DAG.getLoad(VT, Chain,RetAddrFrIdx, NULL, 0);
// Calculate the new stack slot for the return address.
int SlotSize = Is64Bit ? 8 : 4;
- int NewReturnAddrFI =
+ NewReturnAddrFI =
MF.getFrameInfo()->CreateFixedObject(SlotSize, FPDiff-SlotSize);
NewRetAddrFrIdx = DAG.getFrameIndex(NewReturnAddrFI, VT);
Chain = SDOperand(RetAddrFrIdx.Val, 1);
@@ -1461,13 +1470,13 @@
}
...
if (FPDiff)
+ Chain = DAG.getStore(Chain, RetAddrFrIdx, NewRetAddrFrIdx,
+ PseudoSourceValue::getFixedStack(), NewReturnAddrFI);
Looks like this may cause a compile time warning of using undefined value? How about moving the CreateFixedObject call down to the last if (FPDiff)?
+ SmallVector<std::pair<unsigned, SDOperand>, 8> EndangeredVRegs;
Picking on your choice of variable name here.
How about TailCallClobberedVRegs?
+ // Do not flag preceeding copytoreg stuff together with the following stuff.
+ InFlag = SDOperand();
+ // Create virtual register sources for all arguments to force arguments into
+ // (virtual) memory. To force (virtual) loading and guarantee that arguments
+ // sourcing from incomming parameters are not overwritten by each other.
+ for (unsigned i = 0, e = EndangeredVRegs.size(); i != e; i++) {
+ SDOperand Arg = EndangeredVRegs[i].second;
+ unsigned Idx = EndangeredVRegs[i].first;
+ unsigned VReg =
+ MF.getRegInfo().
+ createVirtualRegister(getRegClassFor(Arg.getValueType()));
+ Chain = DAG.getCopyToReg(Chain, VReg, Arg, InFlag);
+ InFlag = Chain.getValue(1);
+ Arg = DAG.getCopyFromReg(Chain, VReg, Arg.getValueType(), InFlag);
+ EndangeredVRegs[i] = std::make_pair(Idx, Arg);
+ Chain = Arg.getValue(1);
+ InFlag = Arg.getValue(2);
+ }
Please refactor this out to a static function.
Otherwise it looks great to me! Please commit after you've updated the patch.Thanks!
Evan