aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/CodeGen/CallingConvLower.h14
-rw-r--r--lib/CodeGen/CallingConvLower.cpp1
-rw-r--r--lib/Target/ARM/ARMISelLowering.cpp26
3 files changed, 38 insertions, 3 deletions
diff --git a/include/llvm/CodeGen/CallingConvLower.h b/include/llvm/CodeGen/CallingConvLower.h
index 3afe3095d4..59e7520d24 100644
--- a/include/llvm/CodeGen/CallingConvLower.h
+++ b/include/llvm/CodeGen/CallingConvLower.h
@@ -164,6 +164,7 @@ private:
SmallVector<uint32_t, 16> UsedRegs;
unsigned FirstByValReg;
bool FirstByValRegValid;
+ bool HasByValInRegPosition; // @LOCALMOD -- ARM only: see comment below.
protected:
ParmContext CallOrPrologue;
@@ -311,6 +312,19 @@ public:
void clearFirstByValReg() { FirstByValReg = 0; FirstByValRegValid = false; }
bool isFirstByValRegValid() const { return FirstByValRegValid; }
+ // @LOCALMOD-BEGIN
+ // We disabled the splitting of byval between registers and memory.
+ // This separate flag indicates that a byval existed. We cannot reuse
+ // isFirstByValRegValid() because that is already used by the broken
+ // mechanism of splitting between stack and regs. We should check
+ // again if this mechanism is still broken later, or try to fix that
+ // mechanism.
+ // NOTE: this is only for ARM, so should be refactored.
+ bool hasByValInRegPosition() const { return HasByValInRegPosition; }
+ void setHasByValInRegPosition() { HasByValInRegPosition = true; }
+ void clearHasByValInRegPosition() { HasByValInRegPosition = false; }
+ // @LOCALMOD-END
+
ParmContext getCallOrPrologue() const { return CallOrPrologue; }
private:
diff --git a/lib/CodeGen/CallingConvLower.cpp b/lib/CodeGen/CallingConvLower.cpp
index b2c976b2a5..81e237effb 100644
--- a/lib/CodeGen/CallingConvLower.cpp
+++ b/lib/CodeGen/CallingConvLower.cpp
@@ -33,6 +33,7 @@ CCState::CCState(CallingConv::ID CC, bool isVarArg, MachineFunction &mf,
StackOffset = 0;
clearFirstByValReg();
+ clearHasByValInRegPosition(); // @LOCALMOD.
UsedRegs.resize((TRI.getNumRegs()+31)/32);
}
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
index 89bed8b823..e1c89e0c42 100644
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -1704,10 +1704,22 @@ ARMTargetLowering::HandleByVal(CCState *State, unsigned &size) const {
"unhandled ParmContext");
// @LOCALMOD-BEGIN
- // This mechanism tries to split a byval argument between registers
- // and the stack. It doesn't work correctly yet, so disable it.
- // This leaves the entire byval argument on the stack.
+ // The original mechanism tries to split a byval argument between registers
+ // and the stack. It doesn't work correctly yet, so disable it.
+ // This leaves the entire byval argument on the stack, and the rest
+ // of the parameters will need to be on the stack as well, to have
+ // the correct order for var-args. We remember the fact that there was
+ // a byval param that forced this, so that we know not to use the
+ // handle var-args reg-save area.
// PR11018.
+ if ((!State->isFirstByValRegValid()) &&
+ (ARM::R0 <= reg) && (reg <= ARM::R3)) {
+ State->setHasByValInRegPosition();
+ }
+ // Confiscate any remaining parameter registers to preclude their
+ // assignment to subsequent parameters.
+ while (State->AllocateReg(GPRArgRegs, 4))
+ ;
return;
// @LOCALMOD-END
@@ -2740,6 +2752,10 @@ ARMTargetLowering::computeRegArea(CCState &CCInfo, MachineFunction &MF,
unsigned NumGPRs;
if (CCInfo.isFirstByValRegValid())
NumGPRs = ARM::R4 - CCInfo.getFirstByValReg();
+ // @LOCALMOD-BEGIN
+ else if (CCInfo.hasByValInRegPosition())
+ NumGPRs = 0;
+ // @LOCALMOD-END
else {
unsigned int firstUnalloced;
firstUnalloced = CCInfo.getFirstUnallocated(GPRArgRegs,
@@ -2770,6 +2786,10 @@ ARMTargetLowering::VarArgStyleRegisters(CCState &CCInfo, SelectionDAG &DAG,
unsigned firstRegToSaveIndex;
if (CCInfo.isFirstByValRegValid())
firstRegToSaveIndex = CCInfo.getFirstByValReg() - ARM::R0;
+ // @LOCALMOD-BEGIN
+ else if (CCInfo.hasByValInRegPosition())
+ firstRegToSaveIndex = 4; // Nothing to save.
+ // @LOCALMOD-END
else {
firstRegToSaveIndex = CCInfo.getFirstUnallocated
(GPRArgRegs, sizeof(GPRArgRegs) / sizeof(GPRArgRegs[0]));