llvm.org GIT mirror llvm / ab8b2f1
Merge r242733, r242734, r242735 and r242742 (r242742 is the interesting patch here, but I picked the others too to get a clean merge since there's been some back-and-forth on this file.) ------------------------------------------------------------------------ r242733 | matze | 2015-07-20 16:17:14 -0700 (Mon, 20 Jul 2015) | 3 lines Revert "ARM: Use SpecificBumpPtrAllocator to fix leak introduced in r241920" This reverts commit r241951. It caused http://llvm.org/PR24190 ------------------------------------------------------------------------ ------------------------------------------------------------------------ r242734 | matze | 2015-07-20 16:17:16 -0700 (Mon, 20 Jul 2015) | 3 lines Revert "ARMLoadStoreOpt: Merge subs/adds into LDRD/STRD; Factor out common code" This reverts commit r241928. This caused http://llvm.org/PR24190 ------------------------------------------------------------------------ ------------------------------------------------------------------------ r242735 | matze | 2015-07-20 16:17:20 -0700 (Mon, 20 Jul 2015) | 3 lines Revert "ARMLoadStoreOptimizer: Create LDRD/STRD on thumb2" This reverts commit r241926. This caused http://llvm.org/PR24190 ------------------------------------------------------------------------ ------------------------------------------------------------------------ r242742 | matze | 2015-07-20 17:18:59 -0700 (Mon, 20 Jul 2015) | 7 lines ARMLoadStoreOptimizer: Create LDRD/STRD on thumb2 Re-apply r241926 with an additional check that r13 and r15 are not used for LDRD/STRD. See http://llvm.org/PR24190. This also already includes the fix from r241951. Differential Revision: http://reviews.llvm.org/D10623 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_37@242907 91177308-0d34-0410-b5e6-96231b3b80d8 Hans Wennborg 5 years ago
2 changed file(s) with 184 addition(s) and 248 deletion(s). Raw diff Collapse all Expand all
117117 };
118118 SpecificBumpPtrAllocator Allocator;
119119 SmallVector Candidates;
120 SmallVector MergeBaseCandidates;
121120
122121 void moveLiveRegsBefore(const MachineBasicBlock &MBB,
123122 MachineBasicBlock::const_iterator Before);
140139 MachineBasicBlock::iterator &MBBI);
141140 bool MergeBaseUpdateLoadStore(MachineInstr *MI);
142141 bool MergeBaseUpdateLSMultiple(MachineInstr *MI);
143 bool MergeBaseUpdateLSDouble(MachineInstr &MI) const;
144142 bool LoadStoreMultipleOpti(MachineBasicBlock &MBB);
145143 bool MergeReturnIntoLDM(MachineBasicBlock &MBB);
146144 };
932930 if (STI->isSwift() && !isNotVFP && (PRegNum % 2) == 1)
933931 CanMergeToLSMulti = false;
934932
933 // LDRD/STRD do not allow SP/PC. LDM/STM do not support it or have it
934 // deprecated; LDM to PC is fine but cannot happen here.
935 if (PReg == ARM::SP || PReg == ARM::PC)
936 CanMergeToLSMulti = CanMergeToLSDouble = false;
937
935938 // Merge following instructions where possible.
936939 for (unsigned I = SIndex+1; I < EIndex; ++I, ++Count) {
937940 int NewOffset = MemOps[I].Offset;
939942 break;
940943 const MachineOperand &MO = getLoadStoreRegOp(*MemOps[I].MI);
941944 unsigned Reg = MO.getReg();
945 if (Reg == ARM::SP || Reg == ARM::PC)
946 break;
947
948 // See if the current load/store may be part of a multi load/store.
942949 unsigned RegNum = MO.isUndef() ? UINT_MAX : TRI->getEncodingValue(Reg);
943
944 // See if the current load/store may be part of a multi load/store.
945950 bool PartOfLSMulti = CanMergeToLSMulti;
946951 if (PartOfLSMulti) {
947 // Cannot load from SP
948 if (Reg == ARM::SP)
949 PartOfLSMulti = false;
950952 // Register numbers must be in ascending order.
951 else if (RegNum <= PRegNum)
953 if (RegNum <= PRegNum)
952954 PartOfLSMulti = false;
953955 // For VFP / NEON load/store multiples, the registers must be
954956 // consecutive and within the limit on the number of registers per
992994 } while (SIndex < EIndex);
993995 }
994996
997 static bool isMatchingDecrement(MachineInstr *MI, unsigned Base,
998 unsigned Bytes, unsigned Limit,
999 ARMCC::CondCodes Pred, unsigned PredReg) {
1000 unsigned MyPredReg = 0;
1001 if (!MI)
1002 return false;
1003
1004 bool CheckCPSRDef = false;
1005 switch (MI->getOpcode()) {
1006 default: return false;
1007 case ARM::tSUBi8:
1008 case ARM::t2SUBri:
1009 case ARM::SUBri:
1010 CheckCPSRDef = true;
1011 break;
1012 case ARM::tSUBspi:
1013 break;
1014 }
1015
1016 // Make sure the offset fits in 8 bits.
1017 if (Bytes == 0 || (Limit && Bytes >= Limit))
1018 return false;
1019
1020 unsigned Scale = (MI->getOpcode() == ARM::tSUBspi ||
1021 MI->getOpcode() == ARM::tSUBi8) ? 4 : 1; // FIXME
1022 if (!(MI->getOperand(0).getReg() == Base &&
1023 MI->getOperand(1).getReg() == Base &&
1024 (MI->getOperand(2).getImm() * Scale) == Bytes &&
1025 getInstrPredicate(MI, MyPredReg) == Pred &&
1026 MyPredReg == PredReg))
1027 return false;
1028
1029 return CheckCPSRDef ? !definesCPSR(MI) : true;
1030 }
1031
1032 static bool isMatchingIncrement(MachineInstr *MI, unsigned Base,
1033 unsigned Bytes, unsigned Limit,
1034 ARMCC::CondCodes Pred, unsigned PredReg) {
1035 unsigned MyPredReg = 0;
1036 if (!MI)
1037 return false;
1038
1039 bool CheckCPSRDef = false;
1040 switch (MI->getOpcode()) {
1041 default: return false;
1042 case ARM::tADDi8:
1043 case ARM::t2ADDri:
1044 case ARM::ADDri:
1045 CheckCPSRDef = true;
1046 break;
1047 case ARM::tADDspi:
1048 break;
1049 }
1050
1051 if (Bytes == 0 || (Limit && Bytes >= Limit))
1052 // Make sure the offset fits in 8 bits.
1053 return false;
1054
1055 unsigned Scale = (MI->getOpcode() == ARM::tADDspi ||
1056 MI->getOpcode() == ARM::tADDi8) ? 4 : 1; // FIXME
1057 if (!(MI->getOperand(0).getReg() == Base &&
1058 MI->getOperand(1).getReg() == Base &&
1059 (MI->getOperand(2).getImm() * Scale) == Bytes &&
1060 getInstrPredicate(MI, MyPredReg) == Pred &&
1061 MyPredReg == PredReg))
1062 return false;
1063
1064 return CheckCPSRDef ? !definesCPSR(MI) : true;
1065 }
1066
9951067 static unsigned getUpdatingLSMultipleOpcode(unsigned Opc,
9961068 ARM_AM::AMSubMode Mode) {
9971069 switch (Opc) {
10571129 case ARM_AM::db: return ARM::VSTMDDB_UPD;
10581130 }
10591131 }
1060 }
1061
1062 /// Check if the given instruction increments or decrements a register and
1063 /// return the amount it is incremented/decremented. Returns 0 if the CPSR flags
1064 /// generated by the instruction are possibly read as well.
1065 static int isIncrementOrDecrement(const MachineInstr &MI, unsigned Reg,
1066 ARMCC::CondCodes Pred, unsigned PredReg) {
1067 bool CheckCPSRDef;
1068 int Scale;
1069 switch (MI.getOpcode()) {
1070 case ARM::tADDi8: Scale = 4; CheckCPSRDef = true; break;
1071 case ARM::tSUBi8: Scale = -4; CheckCPSRDef = true; break;
1072 case ARM::t2SUBri:
1073 case ARM::SUBri: Scale = -1; CheckCPSRDef = true; break;
1074 case ARM::t2ADDri:
1075 case ARM::ADDri: Scale = 1; CheckCPSRDef = true; break;
1076 case ARM::tADDspi: Scale = 4; CheckCPSRDef = false; break;
1077 case ARM::tSUBspi: Scale = -4; CheckCPSRDef = false; break;
1078 default: return 0;
1079 }
1080
1081 unsigned MIPredReg;
1082 if (MI.getOperand(0).getReg() != Reg ||
1083 MI.getOperand(1).getReg() != Reg ||
1084 getInstrPredicate(&MI, MIPredReg) != Pred ||
1085 MIPredReg != PredReg)
1086 return 0;
1087
1088 if (CheckCPSRDef && definesCPSR(&MI))
1089 return 0;
1090 return MI.getOperand(2).getImm() * Scale;
1091 }
1092
1093 /// Searches for an increment or decrement of \p Reg before \p MBBI.
1094 static MachineBasicBlock::iterator
1095 findIncDecBefore(MachineBasicBlock::iterator MBBI, unsigned Reg,
1096 ARMCC::CondCodes Pred, unsigned PredReg, int &Offset) {
1097 Offset = 0;
1098 MachineBasicBlock &MBB = *MBBI->getParent();
1099 MachineBasicBlock::iterator BeginMBBI = MBB.begin();
1100 MachineBasicBlock::iterator EndMBBI = MBB.end();
1101 if (MBBI == BeginMBBI)
1102 return EndMBBI;
1103
1104 // Skip debug values.
1105 MachineBasicBlock::iterator PrevMBBI = std::prev(MBBI);
1106 while (PrevMBBI->isDebugValue() && PrevMBBI != BeginMBBI)
1107 --PrevMBBI;
1108
1109 Offset = isIncrementOrDecrement(*PrevMBBI, Reg, Pred, PredReg);
1110 return Offset == 0 ? EndMBBI : PrevMBBI;
1111 }
1112
1113 /// Searches for a increment or decrement of \p Reg after \p MBBI.
1114 static MachineBasicBlock::iterator
1115 findIncDecAfter(MachineBasicBlock::iterator MBBI, unsigned Reg,
1116 ARMCC::CondCodes Pred, unsigned PredReg, int &Offset) {
1117 Offset = 0;
1118 MachineBasicBlock &MBB = *MBBI->getParent();
1119 MachineBasicBlock::iterator EndMBBI = MBB.end();
1120 MachineBasicBlock::iterator NextMBBI = std::next(MBBI);
1121 // Skip debug values.
1122 while (NextMBBI != EndMBBI && NextMBBI->isDebugValue())
1123 ++NextMBBI;
1124 if (NextMBBI == EndMBBI)
1125 return EndMBBI;
1126
1127 Offset = isIncrementOrDecrement(*NextMBBI, Reg, Pred, PredReg);
1128 return Offset == 0 ? EndMBBI : NextMBBI;
11291132 }
11301133
11311134 /// Fold proceeding/trailing inc/dec of base register into the
11471150 const MachineOperand &BaseOP = MI->getOperand(0);
11481151 unsigned Base = BaseOP.getReg();
11491152 bool BaseKill = BaseOP.isKill();
1153 unsigned Bytes = getLSMultipleTransferSize(MI);
11501154 unsigned PredReg = 0;
11511155 ARMCC::CondCodes Pred = getInstrPredicate(MI, PredReg);
11521156 unsigned Opcode = MI->getOpcode();
11581162 if (MI->getOperand(i).getReg() == Base)
11591163 return false;
11601164
1161 int Bytes = getLSMultipleTransferSize(MI);
1165 bool DoMerge = false;
1166 ARM_AM::AMSubMode Mode = getLoadStoreMultipleSubMode(Opcode);
1167
1168 // Try merging with the previous instruction.
11621169 MachineBasicBlock &MBB = *MI->getParent();
1170 MachineBasicBlock::iterator BeginMBBI = MBB.begin();
11631171 MachineBasicBlock::iterator MBBI(MI);
1164 int Offset;
1165 MachineBasicBlock::iterator MergeInstr
1166 = findIncDecBefore(MBBI, Base, Pred, PredReg, Offset);
1167 ARM_AM::AMSubMode Mode = getLoadStoreMultipleSubMode(Opcode);
1168 if (Mode == ARM_AM::ia && Offset == -Bytes) {
1169 Mode = ARM_AM::db;
1170 } else if (Mode == ARM_AM::ib && Offset == -Bytes) {
1171 Mode = ARM_AM::da;
1172 } else {
1173 MergeInstr = findIncDecAfter(MBBI, Base, Pred, PredReg, Offset);
1174 if (((Mode != ARM_AM::ia && Mode != ARM_AM::ib) || Offset != Bytes) &&
1175 ((Mode != ARM_AM::da && Mode != ARM_AM::db) || Offset != -Bytes))
1176 return false;
1177 }
1178 MBB.erase(MergeInstr);
1172 if (MBBI != BeginMBBI) {
1173 MachineBasicBlock::iterator PrevMBBI = std::prev(MBBI);
1174 while (PrevMBBI != BeginMBBI && PrevMBBI->isDebugValue())
1175 --PrevMBBI;
1176 if (Mode == ARM_AM::ia &&
1177 isMatchingDecrement(PrevMBBI, Base, Bytes, 0, Pred, PredReg)) {
1178 Mode = ARM_AM::db;
1179 DoMerge = true;
1180 } else if (Mode == ARM_AM::ib &&
1181 isMatchingDecrement(PrevMBBI, Base, Bytes, 0, Pred, PredReg)) {
1182 Mode = ARM_AM::da;
1183 DoMerge = true;
1184 }
1185 if (DoMerge)
1186 MBB.erase(PrevMBBI);
1187 }
1188
1189 // Try merging with the next instruction.
1190 MachineBasicBlock::iterator EndMBBI = MBB.end();
1191 if (!DoMerge && MBBI != EndMBBI) {
1192 MachineBasicBlock::iterator NextMBBI = std::next(MBBI);
1193 while (NextMBBI != EndMBBI && NextMBBI->isDebugValue())
1194 ++NextMBBI;
1195 if ((Mode == ARM_AM::ia || Mode == ARM_AM::ib) &&
1196 isMatchingIncrement(NextMBBI, Base, Bytes, 0, Pred, PredReg)) {
1197 DoMerge = true;
1198 } else if ((Mode == ARM_AM::da || Mode == ARM_AM::db) &&
1199 isMatchingDecrement(NextMBBI, Base, Bytes, 0, Pred, PredReg)) {
1200 DoMerge = true;
1201 }
1202 if (DoMerge)
1203 MBB.erase(NextMBBI);
1204 }
1205
1206 if (!DoMerge)
1207 return false;
11791208
11801209 unsigned NewOpc = getUpdatingLSMultipleOpcode(Opcode, Mode);
11811210 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(NewOpc))
12531282
12541283 unsigned Base = getLoadStoreBaseOp(*MI).getReg();
12551284 bool BaseKill = getLoadStoreBaseOp(*MI).isKill();
1285 unsigned Bytes = getLSMultipleTransferSize(MI);
12561286 unsigned Opcode = MI->getOpcode();
12571287 DebugLoc DL = MI->getDebugLoc();
12581288 bool isAM5 = (Opcode == ARM::VLDRD || Opcode == ARM::VLDRS ||
12641294 if (isAM5 && ARM_AM::getAM5Offset(MI->getOperand(2).getImm()) != 0)
12651295 return false;
12661296
1297 bool isLd = isLoadSingle(Opcode);
12671298 // Can't do the merge if the destination register is the same as the would-be
12681299 // writeback register.
12691300 if (MI->getOperand(0).getReg() == Base)
12711302
12721303 unsigned PredReg = 0;
12731304 ARMCC::CondCodes Pred = getInstrPredicate(MI, PredReg);
1274 int Bytes = getLSMultipleTransferSize(MI);
1305 bool DoMerge = false;
1306 ARM_AM::AddrOpc AddSub = ARM_AM::add;
1307 unsigned NewOpc = 0;
1308 // AM2 - 12 bits, thumb2 - 8 bits.
1309 unsigned Limit = isAM5 ? 0 : (isAM2 ? 0x1000 : 0x100);
1310
1311 // Try merging with the previous instruction.
12751312 MachineBasicBlock &MBB = *MI->getParent();
1313 MachineBasicBlock::iterator BeginMBBI = MBB.begin();
12761314 MachineBasicBlock::iterator MBBI(MI);
1277 int Offset;
1278 MachineBasicBlock::iterator MergeInstr
1279 = findIncDecBefore(MBBI, Base, Pred, PredReg, Offset);
1280 unsigned NewOpc;
1281 if (!isAM5 && Offset == Bytes) {
1282 NewOpc = getPreIndexedLoadStoreOpcode(Opcode, ARM_AM::add);
1283 } else if (Offset == -Bytes) {
1284 NewOpc = getPreIndexedLoadStoreOpcode(Opcode, ARM_AM::sub);
1285 } else {
1286 MergeInstr = findIncDecAfter(MBBI, Base, Pred, PredReg, Offset);
1287 if (Offset == Bytes) {
1288 NewOpc = getPostIndexedLoadStoreOpcode(Opcode, ARM_AM::add);
1289 } else if (!isAM5 && Offset == -Bytes) {
1290 NewOpc = getPostIndexedLoadStoreOpcode(Opcode, ARM_AM::sub);
1291 } else
1292 return false;
1293 }
1294 MBB.erase(MergeInstr);
1295
1296 ARM_AM::AddrOpc AddSub = Offset < 0 ? ARM_AM::sub : ARM_AM::add;
1297
1298 bool isLd = isLoadSingle(Opcode);
1315 if (MBBI != BeginMBBI) {
1316 MachineBasicBlock::iterator PrevMBBI = std::prev(MBBI);
1317 while (PrevMBBI != BeginMBBI && PrevMBBI->isDebugValue())
1318 --PrevMBBI;
1319 if (isMatchingDecrement(PrevMBBI, Base, Bytes, Limit, Pred, PredReg)) {
1320 DoMerge = true;
1321 AddSub = ARM_AM::sub;
1322 } else if (!isAM5 &&
1323 isMatchingIncrement(PrevMBBI, Base, Bytes, Limit,Pred,PredReg)) {
1324 DoMerge = true;
1325 }
1326 if (DoMerge) {
1327 NewOpc = getPreIndexedLoadStoreOpcode(Opcode, AddSub);
1328 MBB.erase(PrevMBBI);
1329 }
1330 }
1331
1332 // Try merging with the next instruction.
1333 MachineBasicBlock::iterator EndMBBI = MBB.end();
1334 if (!DoMerge && MBBI != EndMBBI) {
1335 MachineBasicBlock::iterator NextMBBI = std::next(MBBI);
1336 while (NextMBBI != EndMBBI && NextMBBI->isDebugValue())
1337 ++NextMBBI;
1338 if (!isAM5 &&
1339 isMatchingDecrement(NextMBBI, Base, Bytes, Limit, Pred, PredReg)) {
1340 DoMerge = true;
1341 AddSub = ARM_AM::sub;
1342 } else if (isMatchingIncrement(NextMBBI, Base, Bytes, Limit,Pred,PredReg)) {
1343 DoMerge = true;
1344 }
1345 if (DoMerge) {
1346 NewOpc = getPostIndexedLoadStoreOpcode(Opcode, AddSub);
1347 MBB.erase(NextMBBI);
1348 }
1349 }
1350
1351 if (!DoMerge)
1352 return false;
1353
12991354 if (isAM5) {
13001355 // VLDM[SD]_UPD, VSTM[SD]_UPD
13011356 // (There are no base-updating versions of VLDR/VSTR instructions, but the
13121367 if (isAM2) {
13131368 // LDR_PRE, LDR_POST
13141369 if (NewOpc == ARM::LDR_PRE_IMM || NewOpc == ARM::LDRB_PRE_IMM) {
1370 int Offset = AddSub == ARM_AM::sub ? -Bytes : Bytes;
13151371 BuildMI(MBB, MBBI, DL, TII->get(NewOpc), MI->getOperand(0).getReg())
13161372 .addReg(Base, RegState::Define)
13171373 .addReg(Base).addImm(Offset).addImm(Pred).addReg(PredReg);
13181374 } else {
1319 int Imm = ARM_AM::getAM2Opc(AddSub, Bytes, ARM_AM::no_shift);
1375 int Offset = ARM_AM::getAM2Opc(AddSub, Bytes, ARM_AM::no_shift);
13201376 BuildMI(MBB, MBBI, DL, TII->get(NewOpc), MI->getOperand(0).getReg())
13211377 .addReg(Base, RegState::Define)
1322 .addReg(Base).addReg(0).addImm(Imm).addImm(Pred).addReg(PredReg);
1378 .addReg(Base).addReg(0).addImm(Offset).addImm(Pred).addReg(PredReg);
13231379 }
13241380 } else {
1381 int Offset = AddSub == ARM_AM::sub ? -Bytes : Bytes;
13251382 // t2LDR_PRE, t2LDR_POST
13261383 BuildMI(MBB, MBBI, DL, TII->get(NewOpc), MI->getOperand(0).getReg())
13271384 .addReg(Base, RegState::Define)
13331390 // the vestigal zero-reg offset register. When that's fixed, this clause
13341391 // can be removed entirely.
13351392 if (isAM2 && NewOpc == ARM::STR_POST_IMM) {
1336 int Imm = ARM_AM::getAM2Opc(AddSub, Bytes, ARM_AM::no_shift);
1393 int Offset = ARM_AM::getAM2Opc(AddSub, Bytes, ARM_AM::no_shift);
13371394 // STR_PRE, STR_POST
13381395 BuildMI(MBB, MBBI, DL, TII->get(NewOpc), Base)
13391396 .addReg(MO.getReg(), getKillRegState(MO.isKill()))
1340 .addReg(Base).addReg(0).addImm(Imm).addImm(Pred).addReg(PredReg);
1397 .addReg(Base).addReg(0).addImm(Offset).addImm(Pred).addReg(PredReg);
13411398 } else {
1399 int Offset = AddSub == ARM_AM::sub ? -Bytes : Bytes;
13421400 // t2STR_PRE, t2STR_POST
13431401 BuildMI(MBB, MBBI, DL, TII->get(NewOpc), Base)
13441402 .addReg(MO.getReg(), getKillRegState(MO.isKill()))
13471405 }
13481406 MBB.erase(MBBI);
13491407
1350 return true;
1351 }
1352
1353 bool ARMLoadStoreOpt::MergeBaseUpdateLSDouble(MachineInstr &MI) const {
1354 unsigned Opcode = MI.getOpcode();
1355 assert((Opcode == ARM::t2LDRDi8 || Opcode == ARM::t2STRDi8) &&
1356 "Must have t2STRDi8 or t2LDRDi8");
1357 if (MI.getOperand(3).getImm() != 0)
1358 return false;
1359
1360 // Behaviour for writeback is undefined if base register is the same as one
1361 // of the others.
1362 const MachineOperand &BaseOp = MI.getOperand(2);
1363 unsigned Base = BaseOp.getReg();
1364 const MachineOperand &Reg0Op = MI.getOperand(0);
1365 const MachineOperand &Reg1Op = MI.getOperand(1);
1366 if (Reg0Op.getReg() == Base || Reg1Op.getReg() == Base)
1367 return false;
1368
1369 unsigned PredReg;
1370 ARMCC::CondCodes Pred = getInstrPredicate(&MI, PredReg);
1371 MachineBasicBlock::iterator MBBI(MI);
1372 MachineBasicBlock &MBB = *MI.getParent();
1373 int Offset;
1374 MachineBasicBlock::iterator MergeInstr = findIncDecBefore(MBBI, Base, Pred,
1375 PredReg, Offset);
1376 unsigned NewOpc;
1377 if (Offset == 8 || Offset == -8) {
1378 NewOpc = Opcode == ARM::t2LDRDi8 ? ARM::t2LDRD_PRE : ARM::t2STRD_PRE;
1379 } else {
1380 MergeInstr = findIncDecAfter(MBBI, Base, Pred, PredReg, Offset);
1381 if (Offset == 8 || Offset == -8) {
1382 NewOpc = Opcode == ARM::t2LDRDi8 ? ARM::t2LDRD_POST : ARM::t2STRD_POST;
1383 } else
1384 return false;
1385 }
1386 MBB.erase(MergeInstr);
1387
1388 DebugLoc DL = MI.getDebugLoc();
1389 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(NewOpc));
1390 if (NewOpc == ARM::t2LDRD_PRE || NewOpc == ARM::t2LDRD_POST) {
1391 MIB.addOperand(Reg0Op).addOperand(Reg1Op)
1392 .addReg(BaseOp.getReg(), RegState::Define);
1393 } else {
1394 assert(NewOpc == ARM::t2STRD_PRE || NewOpc == ARM::t2STRD_POST);
1395 MIB.addReg(BaseOp.getReg(), RegState::Define)
1396 .addOperand(Reg0Op).addOperand(Reg1Op);
1397 }
1398 MIB.addReg(BaseOp.getReg(), RegState::Kill)
1399 .addImm(Offset).addImm(Pred).addReg(PredReg);
1400 assert(TII->get(Opcode).getNumOperands() == 6 &&
1401 TII->get(NewOpc).getNumOperands() == 7 &&
1402 "Unexpected number of operands in Opcode specification.");
1403
1404 // Transfer implicit operands.
1405 for (const MachineOperand &MO : MI.implicit_operands())
1406 MIB.addOperand(MO);
1407 MIB->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
1408
1409 MBB.erase(MBBI);
14101408 return true;
14111409 }
14121410
16171615 ARMCC::CondCodes CurrPred = ARMCC::AL;
16181616 unsigned Position = 0;
16191617 assert(Candidates.size() == 0);
1620 assert(MergeBaseCandidates.size() == 0);
16211618 LiveRegsValid = false;
16221619
16231620 for (MachineBasicBlock::iterator I = MBB.end(), MBBI; I != MBB.begin();
16961693 MBBI = I;
16971694 --Position;
16981695 // Fallthrough to look into existing chain.
1699 } else if (MBBI->isDebugValue()) {
1696 } else if (MBBI->isDebugValue())
17001697 continue;
1701 } else if (MBBI->getOpcode() == ARM::t2LDRDi8 ||
1702 MBBI->getOpcode() == ARM::t2STRDi8) {
1703 // ARMPreAllocLoadStoreOpt has already formed some LDRD/STRD instructions
1704 // remember them because we may still be able to merge add/sub into them.
1705 MergeBaseCandidates.push_back(MBBI);
1706 }
1707
17081698
17091699 // If we are here then the chain is broken; Extract candidates for a merge.
17101700 if (MemOps.size() > 0) {
17351725 if (Merged) {
17361726 Changed = true;
17371727 unsigned Opcode = Merged->getOpcode();
1738 if (Opcode == ARM::t2STRDi8 || Opcode == ARM::t2LDRDi8)
1739 MergeBaseUpdateLSDouble(*Merged);
1740 else
1728 if (Opcode != ARM::t2STRDi8 && Opcode != ARM::t2LDRDi8)
17411729 MergeBaseUpdateLSMultiple(Merged);
17421730 } else {
17431731 for (MachineInstr *MI : Candidate->Instrs) {
17521740 }
17531741 }
17541742 Candidates.clear();
1755 // Try to fold add/sub into the LDRD/STRD formed by ARMPreAllocLoadStoreOpt.
1756 for (MachineInstr *MI : MergeBaseCandidates)
1757 MergeBaseUpdateLSDouble(*MI);
1758 MergeBaseCandidates.clear();
17591743
17601744 return Changed;
17611745 }
111111 }
112112
113113 ; CHECK-LABEL: strd_spill_ldrd_reload:
114 ; A8: strd r1, r0, [sp, #-8]!
115 ; M3: strd r1, r0, [sp, #-8]!
116 ; BASIC: strd r1, r0, [sp, #-8]!
117 ; GREEDY: strd r0, r1, [sp, #-8]!
114 ; A8: strd r1, r0, [sp]
115 ; M3: strd r1, r0, [sp]
116 ; BASIC: strd r1, r0, [sp]
117 ; GREEDY: strd r0, r1, [sp]
118118 ; CHECK: @ InlineAsm Start
119119 ; CHECK: @ InlineAsm End
120120 ; A8: ldrd r2, r1, [sp]
130130 ret void
131131 }
132132
133 declare void @extfunc2(i32*, i32, i32)
134
135 ; CHECK-LABEL: ldrd_postupdate_dec:
136 ; CHECK: ldrd r1, r2, [r0], #-8
137 ; CHECK-NEXT: bl{{x?}} _extfunc
138 define void @ldrd_postupdate_dec(i32* %p0) {
139 %p0.1 = getelementptr i32, i32* %p0, i32 1
140 %v0 = load i32, i32* %p0
141 %v1 = load i32, i32* %p0.1
142 %p1 = getelementptr i32, i32* %p0, i32 -2
143 call void @extfunc2(i32* %p1, i32 %v0, i32 %v1)
144 ret void
145 }
146
147 ; CHECK-LABEL: ldrd_postupdate_inc:
148 ; CHECK: ldrd r1, r2, [r0], #8
149 ; CHECK-NEXT: bl{{x?}} _extfunc
150 define void @ldrd_postupdate_inc(i32* %p0) {
151 %p0.1 = getelementptr i32, i32* %p0, i32 1
152 %v0 = load i32, i32* %p0
153 %v1 = load i32, i32* %p0.1
154 %p1 = getelementptr i32, i32* %p0, i32 2
155 call void @extfunc2(i32* %p1, i32 %v0, i32 %v1)
156 ret void
157 }
158
159 ; CHECK-LABEL: strd_postupdate_dec:
160 ; CHECK: strd r1, r2, [r0], #-8
161 ; CHECK-NEXT: bx lr
162 define i32* @strd_postupdate_dec(i32* %p0, i32 %v0, i32 %v1) {
163 %p0.1 = getelementptr i32, i32* %p0, i32 1
164 store i32 %v0, i32* %p0
165 store i32 %v1, i32* %p0.1
166 %p1 = getelementptr i32, i32* %p0, i32 -2
167 ret i32* %p1
168 }
169
170 ; CHECK-LABEL: strd_postupdate_inc:
171 ; CHECK: strd r1, r2, [r0], #8
172 ; CHECK-NEXT: bx lr
173 define i32* @strd_postupdate_inc(i32* %p0, i32 %v0, i32 %v1) {
174 %p0.1 = getelementptr i32, i32* %p0, i32 1
175 store i32 %v0, i32* %p0
176 store i32 %v1, i32* %p0.1
177 %p1 = getelementptr i32, i32* %p0, i32 2
178 ret i32* %p1
179 }
180
181133 declare void @llvm.lifetime.start(i64, i8* nocapture) nounwind
182134 declare void @llvm.lifetime.end(i64, i8* nocapture) nounwind