diff --git a/bolt/include/bolt/Core/MCPlusBuilder.h b/bolt/include/bolt/Core/MCPlusBuilder.h --- a/bolt/include/bolt/Core/MCPlusBuilder.h +++ b/bolt/include/bolt/Core/MCPlusBuilder.h @@ -182,6 +182,29 @@ removeAnnotationInst(SrcInst); } +public: + /// Return iterator range covering def operands. + iterator_range defOperands(MCInst &Inst) const { + return make_range(Inst.begin(), + Inst.begin() + Info->get(Inst.getOpcode()).getNumDefs()); + } + + iterator_range defOperands(const MCInst &Inst) const { + return make_range(Inst.begin(), + Inst.begin() + Info->get(Inst.getOpcode()).getNumDefs()); + } + + /// Return iterator range covering prime use operands. + iterator_range useOperands(MCInst &Inst) const { + return make_range(Inst.begin() + Info->get(Inst.getOpcode()).getNumDefs(), + Inst.begin() + MCPlus::getNumPrimeOperands(Inst)); + } + + iterator_range useOperands(const MCInst &Inst) const { + return make_range(Inst.begin() + Info->get(Inst.getOpcode()).getNumDefs(), + Inst.begin() + MCPlus::getNumPrimeOperands(Inst)); + } + public: class InstructionIterator { public: diff --git a/bolt/include/bolt/Passes/LivenessAnalysis.h b/bolt/include/bolt/Passes/LivenessAnalysis.h --- a/bolt/include/bolt/Passes/LivenessAnalysis.h +++ b/bolt/include/bolt/Passes/LivenessAnalysis.h @@ -136,12 +136,9 @@ } } const MCInstrDesc &InstInfo = BC.MII->get(Point.getOpcode()); - for (unsigned I = 0, E = Point.getNumOperands(); I != E; ++I) { - if (!Point.getOperand(I).isReg() || I < InstInfo.getNumDefs()) - continue; - Used |= BC.MIB->getAliases(Point.getOperand(I).getReg(), - /*OnlySmaller=*/false); - } + for (const MCOperand &Op : BC.MIB->useOperands(Point)) + if (Op.isReg()) + Used |= BC.MIB->getAliases(Op.getReg(), /*OnlySmaller=*/false); for (MCPhysReg ImplicitUse : InstInfo.implicit_uses()) Used |= BC.MIB->getAliases(ImplicitUse, false); if (IsCall && diff --git a/bolt/lib/Core/MCPlusBuilder.cpp b/bolt/lib/Core/MCPlusBuilder.cpp --- a/bolt/lib/Core/MCPlusBuilder.cpp +++ b/bolt/lib/Core/MCPlusBuilder.cpp @@ -332,8 +332,7 @@ for (MCPhysReg ImplicitDef : InstInfo.implicit_defs()) Regs |= getAliases(ImplicitDef, /*OnlySmaller=*/false); - for (unsigned I = 0, E = InstInfo.getNumDefs(); I != E; ++I) { - const MCOperand &Operand = Inst.getOperand(I); + for (const MCOperand &Operand : defOperands(Inst)) { assert(Operand.isReg()); Regs |= getAliases(Operand.getReg(), /*OnlySmaller=*/false); } @@ -366,8 +365,7 @@ for (MCPhysReg ImplicitDef : InstInfo.implicit_defs()) Regs |= getAliases(ImplicitDef, /*OnlySmaller=*/true); - for (unsigned I = 0, E = InstInfo.getNumDefs(); I != E; ++I) { - const MCOperand &Operand = Inst.getOperand(I); + for (const MCOperand &Operand : defOperands(Inst)) { assert(Operand.isReg()); Regs |= getAliases(Operand.getReg(), /*OnlySmaller=*/true); } @@ -414,12 +412,9 @@ for (MCPhysReg ImplicitUse : InstInfo.implicit_uses()) Regs |= getAliases(ImplicitUse, /*OnlySmaller=*/true); - for (unsigned I = InstInfo.getNumDefs(), E = InstInfo.getNumOperands(); - I != E; ++I) { - if (!Inst.getOperand(I).isReg()) - continue; - Regs |= getAliases(Inst.getOperand(I).getReg(), /*OnlySmaller=*/true); - } + for (const MCOperand &Operand : useOperands(Inst)) + if (Operand.isReg()) + Regs |= getAliases(Operand.getReg(), /*OnlySmaller=*/true); } bool MCPlusBuilder::hasDefOfPhysReg(const MCInst &MI, unsigned Reg) const { diff --git a/bolt/lib/Passes/ShrinkWrapping.cpp b/bolt/lib/Passes/ShrinkWrapping.cpp --- a/bolt/lib/Passes/ShrinkWrapping.cpp +++ b/bolt/lib/Passes/ShrinkWrapping.cpp @@ -263,13 +263,9 @@ return; // Check if the definition of SP comes from FP -- in this case, this // value may need to be updated depending on our stack layout changes - const MCInstrDesc &InstInfo = BC.MII->get(Point.getOpcode()); - unsigned NumDefs = InstInfo.getNumDefs(); - bool UsesFP = llvm::any_of( - llvm::drop_begin(MCPlus::primeOperands(Point), NumDefs), - [&](MCOperand &Op) { - return Op.isReg() && Op.getReg() == BC.MIB->getFramePointer(); - }); + bool UsesFP = llvm::any_of(BC.MIB->useOperands(Point), [&](MCOperand &Op) { + return Op.isReg() && Op.getReg() == BC.MIB->getFramePointer(); + }); if (!UsesFP) return; diff --git a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp --- a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp +++ b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp @@ -177,10 +177,7 @@ bool isLoadFromStack(const MCInst &Inst) const { if (!isLoad(Inst)) return false; - const MCInstrDesc &InstInfo = Info->get(Inst.getOpcode()); - unsigned NumDefs = InstInfo.getNumDefs(); - for (unsigned I = NumDefs, E = InstInfo.getNumOperands(); I < E; ++I) { - const MCOperand &Operand = Inst.getOperand(I); + for (const MCOperand &Operand : useOperands(Inst)) { if (!Operand.isReg()) continue; unsigned Reg = Operand.getReg(); diff --git a/bolt/lib/Target/X86/X86MCPlusBuilder.cpp b/bolt/lib/Target/X86/X86MCPlusBuilder.cpp --- a/bolt/lib/Target/X86/X86MCPlusBuilder.cpp +++ b/bolt/lib/Target/X86/X86MCPlusBuilder.cpp @@ -1148,13 +1148,9 @@ break; } - const MCInstrDesc &MCII = Info->get(Inst.getOpcode()); - for (int I = 0, E = MCII.getNumDefs(); I != E; ++I) { - const MCOperand &Operand = Inst.getOperand(I); - if (Operand.isReg() && Operand.getReg() == X86::RSP) - return true; - } - return false; + return any_of(defOperands(Inst), [](const MCOperand &Op) { + return Op.isReg() && Op.getReg() == X86::RSP; + }); } bool @@ -1287,19 +1283,11 @@ // If potential leak, check if it is not just writing to itself/sp/bp if (DoesLeak) { - for (int I = 0, E = NumDefs; I != E; ++I) { - const MCOperand &Operand = Inst.getOperand(I); - if (HasFramePointer && Operand.isReg() && - SPBPAliases[Operand.getReg()]) { - DoesLeak = false; - break; - } - if (!HasFramePointer && Operand.isReg() && - SPAliases[Operand.getReg()]) { - DoesLeak = false; - break; - } - } + DoesLeak = !any_of(defOperands(Inst), [&](const MCOperand &Operand) { + assert(Operand.isReg()); + MCPhysReg Reg = Operand.getReg(); + return HasFramePointer ? SPBPAliases[Reg] : SPAliases[Reg]; + }); } return DoesLeak; } @@ -3121,17 +3109,9 @@ // Check if the target address expression used in the original indirect call // uses the stack pointer, which we are going to clobber. static BitVector SPAliases(getAliases(X86::RSP)); - bool UsesSP = false; - // Skip defs. - for (unsigned I = Info->get(CallInst.getOpcode()).getNumDefs(), - E = MCPlus::getNumPrimeOperands(CallInst); - I != E; ++I) { - const MCOperand &Operand = CallInst.getOperand(I); - if (Operand.isReg() && SPAliases[Operand.getReg()]) { - UsesSP = true; - break; - } - } + bool UsesSP = any_of(useOperands(CallInst), [&](const MCOperand &Op) { + return Op.isReg() && SPAliases[Op.getReg()]; + }); InstructionListType Insts; MCPhysReg TempReg = getIntArgRegister(0);