Index: lib/Target/ARM/ARMISelDAGToDAG.cpp |
diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp |
index 69415792aacc548a6112870d578c648f089b18dd..ada60bfd0719aba705f96fc038e482b7d2339a66 100644 |
--- a/lib/Target/ARM/ARMISelDAGToDAG.cpp |
+++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp |
@@ -112,21 +112,24 @@ public: |
bool SelectAddrModeImm12(SDValue N, SDValue &Base, SDValue &OffImm); |
bool SelectLdStSOReg(SDValue N, SDValue &Base, SDValue &Offset, SDValue &Opc); |
- AddrMode2Type SelectAddrMode2Worker(SDValue N, SDValue &Base, |
+ AddrMode2Type SelectAddrMode2Worker(SDNode *Op, SDValue N, SDValue &Base, |
SDValue &Offset, SDValue &Opc); |
- bool SelectAddrMode2Base(SDValue N, SDValue &Base, SDValue &Offset, |
+ bool SelectAddrMode2Base(SDNode *Op, |
+ SDValue N, SDValue &Base, SDValue &Offset, |
SDValue &Opc) { |
- return SelectAddrMode2Worker(N, Base, Offset, Opc) == AM2_BASE; |
+ return SelectAddrMode2Worker(Op, N, Base, Offset, Opc) == AM2_BASE; |
} |
- bool SelectAddrMode2ShOp(SDValue N, SDValue &Base, SDValue &Offset, |
+ bool SelectAddrMode2ShOp(SDNode *Op, |
+ SDValue N, SDValue &Base, SDValue &Offset, |
SDValue &Opc) { |
- return SelectAddrMode2Worker(N, Base, Offset, Opc) == AM2_SHOP; |
+ return SelectAddrMode2Worker(Op, N, Base, Offset, Opc) == AM2_SHOP; |
} |
- bool SelectAddrMode2(SDValue N, SDValue &Base, SDValue &Offset, |
+ bool SelectAddrMode2(SDNode *Op, |
+ SDValue N, SDValue &Base, SDValue &Offset, |
SDValue &Opc) { |
- SelectAddrMode2Worker(N, Base, Offset, Opc); |
+ SelectAddrMode2Worker(Op, N, Base, Offset, Opc); |
// return SelectAddrMode2ShOp(N, Base, Offset, Opc); |
// This always matches one way or another. |
return true; |
@@ -146,7 +149,7 @@ public: |
bool SelectAddrMode2OffsetImmPre(SDNode *Op, SDValue N, |
SDValue &Offset, SDValue &Opc); |
bool SelectAddrOffsetNone(SDValue N, SDValue &Base); |
- bool SelectAddrMode3(SDValue N, SDValue &Base, |
+ bool SelectAddrMode3(SDNode *Op, SDValue N, SDValue &Base, |
SDValue &Offset, SDValue &Opc); |
bool SelectAddrMode3Offset(SDNode *Op, SDValue N, |
SDValue &Offset, SDValue &Opc); |
@@ -514,6 +517,18 @@ bool ARMDAGToDAGISel::SelectRegShifterOperand(SDValue N, |
return true; |
} |
+// @LOCALMOD-START |
+static bool ShouldOperandBeUnwrappedForUseAsBaseAddress( |
+ SDValue& N, const ARMSubtarget* Subtarget) { |
+ assert (N.getOpcode() == ARMISD::Wrapper); |
+ // Never use this transformation if constant island pools are disallowed |
+ if (!Subtarget->useConstIslands()) return false; |
+ |
+ // explain why we do not want to use this for TargetGlobalAddress |
+ if (N.getOperand(0).getOpcode() != ISD::TargetGlobalAddress) return true; |
+ return false; |
+} |
+// @LOCALMOD-END |
bool ARMDAGToDAGISel::SelectAddrModeImm12(SDValue N, |
SDValue &Base, |
@@ -532,7 +547,8 @@ bool ARMDAGToDAGISel::SelectAddrModeImm12(SDValue N, |
} |
if (N.getOpcode() == ARMISD::Wrapper && |
- N.getOperand(0).getOpcode() != ISD::TargetGlobalAddress) { |
+ // @LOCALMOD |
+ ShouldOperandBeUnwrappedForUseAsBaseAddress(N, Subtarget)) { |
Base = N.getOperand(0); |
} else |
Base = N; |
@@ -566,6 +582,11 @@ bool ARMDAGToDAGISel::SelectAddrModeImm12(SDValue N, |
bool ARMDAGToDAGISel::SelectLdStSOReg(SDValue N, SDValue &Base, SDValue &Offset, |
SDValue &Opc) { |
+ // @LOCALMOD-BEGIN |
+ // Disallow offsets of Reg + Reg (which may escape sandbox). |
+ if (Subtarget->isTargetNaCl()) |
+ return false; |
+ // @LOCALMOD-END |
if (N.getOpcode() == ISD::MUL && |
((!Subtarget->isLikeA9() && !Subtarget->isSwift()) || N.hasOneUse())) { |
if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { |
@@ -661,10 +682,19 @@ bool ARMDAGToDAGISel::SelectLdStSOReg(SDValue N, SDValue &Base, SDValue &Offset, |
//----- |
-AddrMode2Type ARMDAGToDAGISel::SelectAddrMode2Worker(SDValue N, |
+AddrMode2Type ARMDAGToDAGISel::SelectAddrMode2Worker(SDNode *Op, |
+ SDValue N, |
SDValue &Base, |
SDValue &Offset, |
SDValue &Opc) { |
+ // @LOCALMOD-START |
+ // Avoid two reg addressing mode for loads and stores |
+ const bool restrict_addressing_modes_for_nacl = Subtarget->isTargetNaCl() && |
+ (Op->getOpcode() == ISD::LOAD || Op->getOpcode() == ISD::STORE); |
+ // This is neither a sandboxable load nor a sandboxable store. |
+ if (!restrict_addressing_modes_for_nacl) { |
+ // @LOCALMOD-END |
+ |
if (N.getOpcode() == ISD::MUL && |
(!(Subtarget->isLikeA9() || Subtarget->isSwift()) || N.hasOneUse())) { |
if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { |
@@ -688,6 +718,7 @@ AddrMode2Type ARMDAGToDAGISel::SelectAddrMode2Worker(SDValue N, |
} |
} |
} |
+ } // @LOCALMOD |
if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB && |
// ISD::OR that is equivalent to an ADD. |
@@ -697,7 +728,8 @@ AddrMode2Type ARMDAGToDAGISel::SelectAddrMode2Worker(SDValue N, |
int FI = cast<FrameIndexSDNode>(N)->getIndex(); |
Base = CurDAG->getTargetFrameIndex(FI, TLI->getPointerTy()); |
} else if (N.getOpcode() == ARMISD::Wrapper && |
- N.getOperand(0).getOpcode() != ISD::TargetGlobalAddress) { |
+ // @LOCALMOD |
+ ShouldOperandBeUnwrappedForUseAsBaseAddress(N, Subtarget)) { |
Base = N.getOperand(0); |
} |
Offset = CurDAG->getRegister(0, MVT::i32); |
@@ -740,6 +772,25 @@ AddrMode2Type ARMDAGToDAGISel::SelectAddrMode2Worker(SDValue N, |
MVT::i32); |
return AM2_BASE; |
} |
+ |
+ // @LOCALMOD-START |
+ // Keep load and store addressing modes simple |
+ if (restrict_addressing_modes_for_nacl) { |
+ Base = N; |
+ if (N.getOpcode() == ISD::FrameIndex) { |
+ int FI = cast<FrameIndexSDNode>(N)->getIndex(); |
+ Base = CurDAG->getTargetFrameIndex(FI, |
+ getTargetLowering()->getPointerTy()); |
+ } else if (N.getOpcode() == ARMISD::Wrapper) { |
+ Base = N.getOperand(0); |
+ } |
+ Offset = CurDAG->getRegister(0, MVT::i32); |
+ Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(ARM_AM::add, 0, |
+ ARM_AM::no_shift), |
+ MVT::i32); |
+ return AM2_BASE; |
+ } |
+ // @LOCALMOD-END |
// Otherwise this is R +/- [possibly shifted] R. |
ARM_AM::AddrOpc AddSub = N.getOpcode() != ISD::SUB ? ARM_AM::add:ARM_AM::sub; |
@@ -808,13 +859,25 @@ bool ARMDAGToDAGISel::SelectAddrMode2OffsetReg(SDNode *Op, SDValue N, |
if (isScaledConstantInRange(N, /*Scale=*/1, 0, 0x1000, Val)) |
return false; |
+ // @LOCALMOD-BEGIN |
+ // Avoid two reg addressing mode for loads and stores |
+ const bool restrict_addressing_modes_for_nacl = Subtarget->isTargetNaCl() && |
+ (Op->getOpcode() == ISD::LOAD || Op->getOpcode() == ISD::STORE); |
+ // @LOCALMOD-END |
+ |
Offset = N; |
ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOpcode()); |
unsigned ShAmt = 0; |
if (ShOpcVal != ARM_AM::no_shift) { |
// Check to see if the RHS of the shift is a constant, if not, we can't fold |
// it. |
- if (ConstantSDNode *Sh = dyn_cast<ConstantSDNode>(N.getOperand(1))) { |
+ |
+ //if (ConstantSDNode *Sh = dyn_cast<ConstantSDNode>(N.getOperand(1))) { |
+ ConstantSDNode *Sh = dyn_cast<ConstantSDNode>(N.getOperand(1)); |
+ // @LOCALMOD-BEGIN |
+ // Neither a sandboxable load nor a sandboxable store. |
+ if (!restrict_addressing_modes_for_nacl && Sh ) { |
+ // @LOCALMOD-END |
ShAmt = Sh->getZExtValue(); |
if (isShifterOpProfitable(N, ShOpcVal, ShAmt)) |
Offset = N.getOperand(0); |
@@ -877,9 +940,15 @@ bool ARMDAGToDAGISel::SelectAddrOffsetNone(SDValue N, SDValue &Base) { |
return true; |
} |
-bool ARMDAGToDAGISel::SelectAddrMode3(SDValue N, |
+bool ARMDAGToDAGISel::SelectAddrMode3(SDNode *Op, SDValue N, |
SDValue &Base, SDValue &Offset, |
SDValue &Opc) { |
+ // @LOCALMOD-START |
+ // Avoid two reg addressing mode for loads and stores |
+ const bool restrict_addressing_modes_for_nacl = Subtarget->isTargetNaCl() && |
+ (Op->getOpcode() == ISD::LOAD || Op->getOpcode() == ISD::STORE); |
+ if (!restrict_addressing_modes_for_nacl) { |
+ // @LOCALMOD-END |
if (N.getOpcode() == ISD::SUB) { |
// X - C is canonicalize to X + -C, no need to handle it here. |
Base = N.getOperand(0); |
@@ -887,6 +956,7 @@ bool ARMDAGToDAGISel::SelectAddrMode3(SDValue N, |
Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::sub, 0),MVT::i32); |
return true; |
} |
+ } // @LOCALMOD-END |
if (!CurDAG->isBaseWithConstantOffset(N)) { |
Base = N; |
@@ -919,6 +989,16 @@ bool ARMDAGToDAGISel::SelectAddrMode3(SDValue N, |
return true; |
} |
+ // @LOCALMOD-START |
+ // A sandboxable load or a sandboxable store. |
+ if (restrict_addressing_modes_for_nacl) { |
+ Base = N; |
+ Offset = CurDAG->getRegister(0, MVT::i32); |
+ Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add, 0),MVT::i32); |
+ return true; |
+ } |
+ // @LOCALMOD-END |
+ |
Base = N.getOperand(0); |
Offset = N.getOperand(1); |
Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add, 0), MVT::i32); |
@@ -953,7 +1033,8 @@ bool ARMDAGToDAGISel::SelectAddrMode5(SDValue N, |
int FI = cast<FrameIndexSDNode>(N)->getIndex(); |
Base = CurDAG->getTargetFrameIndex(FI, TLI->getPointerTy()); |
} else if (N.getOpcode() == ARMISD::Wrapper && |
- N.getOperand(0).getOpcode() != ISD::TargetGlobalAddress) { |
+ // @LOCALMOD |
+ ShouldOperandBeUnwrappedForUseAsBaseAddress(N, Subtarget)) { |
Base = N.getOperand(0); |
} |
Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::add, 0), |
@@ -2459,6 +2540,8 @@ SDNode *ARMDAGToDAGISel::Select(SDNode *N) { |
!(Subtarget->hasV6T2Ops() && Val <= 0xffff)); // MOVW |
} |
+ if (!Subtarget->useConstIslands()) UseCP = false; // @LOCALMOD |
+ |
if (UseCP) { |
SDValue CPIdx = CurDAG->getTargetConstantPool( |
ConstantInt::get(Type::getInt32Ty(*CurDAG->getContext()), Val), |