#include "llvm/IR/Function.h" // To access Function attributes
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
using namespace llvm;
static bool VerifyLowRegs(MachineInstr *MI) {
unsigned Opc = MI->getOpcode();
- bool isPCOk = (Opc == ARM::t2LDMIA_RET || Opc == ARM::t2LDMIA ||
- Opc == ARM::t2LDMDB || Opc == ARM::t2LDMIA_UPD ||
- Opc == ARM::t2LDMDB_UPD);
- bool isLROk = (Opc == ARM::t2STMIA_UPD || Opc == ARM::t2STMDB_UPD);
+ bool isPCOk = (Opc == ARM::t2LDMIA_RET || Opc == ARM::t2LDMIA_UPD);
+ bool isLROk = (Opc == ARM::t2STMDB_UPD);
bool isSPOk = isPCOk || isLROk;
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
const MachineOperand &MO = MI->getOperand(i);
if (MI->getOperand(1).getReg() == ARM::SP) {
Opc = Entry.NarrowOpc2;
ImmLimit = Entry.Imm2Limit;
- HasOffReg = false;
}
Scale = 4;
HasShift = true;
OpNum = 4;
break;
- case ARM::t2LDMIA:
- case ARM::t2LDMDB: {
+ case ARM::t2LDMIA: {
unsigned BaseReg = MI->getOperand(0).getReg();
- if (!isARMLowRegister(BaseReg) || Entry.WideOpc != ARM::t2LDMIA)
- return false;
+ assert(isARMLowRegister(BaseReg));
// For the non-writeback version (this one), the base register must be
// one of the registers being loaded.
bool isOK = false;
- for (unsigned i = 4; i < MI->getNumOperands(); ++i) {
+ for (unsigned i = 3; i < MI->getNumOperands(); ++i) {
if (MI->getOperand(i).getReg() == BaseReg) {
isOK = true;
break;
break;
}
case ARM::t2LDMIA_UPD:
- case ARM::t2LDMDB_UPD:
case ARM::t2STMIA_UPD:
case ARM::t2STMDB_UPD: {
OpNum = 0;
unsigned OffsetReg = 0;
bool OffsetKill = false;
+ bool OffsetInternal = false;
if (HasShift) {
OffsetReg = MI->getOperand(2).getReg();
OffsetKill = MI->getOperand(2).isKill();
+ OffsetInternal = MI->getOperand(2).isInternalRead();
if (MI->getOperand(3).getImm())
// Thumb1 addressing mode doesn't support shift.
assert((!HasShift || OffsetReg) && "Invalid so_reg load / store address!");
if (HasOffReg)
- MIB.addReg(OffsetReg, getKillRegState(OffsetKill));
+ MIB.addReg(OffsetReg, getKillRegState(OffsetKill) |
+ getInternalReadRegState(OffsetInternal));
}
// Transfer the rest of operands.
if (Entry.LowRegs1 && !VerifyLowRegs(MI))
return false;
- if (MI->mayLoad() || MI->mayStore())
+ if (MI->mayLoadOrStore())
return ReduceLoadStore(MBB, MI, Entry);
switch (Opc) {
// Yes, CPSR could be livein.
bool LiveCPSR = MBB.isLiveIn(ARM::CPSR);
- MachineInstr *BundleMI = 0;
+ MachineInstr *BundleMI = nullptr;
- CPSRDef = 0;
+ CPSRDef = nullptr;
HighLatencyCPSR = false;
// Check predecessors for the latest CPSRDef.
LiveCPSR = UpdateCPSRDef(*MI, LiveCPSR, DefCPSR);
if (MI->isCall()) {
// Calls don't really set CPSR.
- CPSRDef = 0;
+ CPSRDef = nullptr;
HighLatencyCPSR = false;
IsSelfLoop = false;
} else if (DefCPSR) {
}
bool Thumb2SizeReduce::runOnMachineFunction(MachineFunction &MF) {
- const TargetMachine &TM = MF.getTarget();
- TII = static_cast<const Thumb2InstrInfo*>(TM.getInstrInfo());
- STI = &TM.getSubtarget<ARMSubtarget>();
+ STI = &static_cast<const ARMSubtarget &>(MF.getSubtarget());
+ if (STI->isThumb1Only() || STI->prefers32BitThumb())
+ return false;
+
+ TII = static_cast<const Thumb2InstrInfo *>(STI->getInstrInfo());
// Optimizing / minimizing size?
- AttributeSet FnAttrs = MF.getFunction()->getAttributes();
- OptimizeSize = FnAttrs.hasAttribute(AttributeSet::FunctionIndex,
- Attribute::OptimizeForSize);
- MinimizeSize = STI->isMinSize();
+ OptimizeSize = MF.getFunction()->hasFnAttribute(Attribute::OptimizeForSize);
+ MinimizeSize = MF.getFunction()->hasFnAttribute(Attribute::MinSize);
BlockInfo.clear();
BlockInfo.resize(MF.getNumBlockIDs());