Skip to content

Commit

Permalink
MC: Add MCInstrDesc::mayAffectControlFlow() method.
Browse files Browse the repository at this point in the history
MC disassembler clients (LLDB) are interested in querying if an
instruction may affect control flow other than by virtue of being
an explicit branch instruction. For example, instructions which
write directly to the PC on some architectures.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@170610 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
Jim Grosbach committed Dec 19, 2012
1 parent 16f3204 commit fbf3b4a
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 13 deletions.
30 changes: 28 additions & 2 deletions include/llvm/MC/MCInstrDesc.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
#define LLVM_MC_MCINSTRDESC_H

#include "llvm/Support/DataTypes.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCInst.h"

namespace llvm {

Expand Down Expand Up @@ -258,6 +260,17 @@ class MCInstrDesc {
return isBranch() & isBarrier() & !isIndirectBranch();
}

/// Return true if this is a branch or an instruction which directly
/// writes to the program counter. Considered 'may' affect rather than
/// 'does' affect as things like predication are not taken into account.
bool mayAffectControlFlow(const MCInst &MI, const MCRegisterInfo &RI) const {
if (isBranch() || isCall() || isReturn() || isIndirectBranch())
return true;
unsigned PC = RI.getProgramCounter();
if (PC == 0) return false;
return hasDefOfPhysReg(MI, PC, RI);
}

/// isPredicable - Return true if this instruction has a predicate operand
/// that controls execution. It may be set to 'always', or may be set to other
/// values. There are various methods in TargetInstrInfo that can be used to
Expand Down Expand Up @@ -502,13 +515,26 @@ class MCInstrDesc {

/// hasImplicitDefOfPhysReg - Return true if this instruction implicitly
/// defines the specified physical register.
bool hasImplicitDefOfPhysReg(unsigned Reg) const {
bool hasImplicitDefOfPhysReg(unsigned Reg,
const MCRegisterInfo *MRI = 0) const {
if (const uint16_t *ImpDefs = ImplicitDefs)
for (; *ImpDefs; ++ImpDefs)
if (*ImpDefs == Reg) return true;
if (*ImpDefs == Reg || (MRI && MRI->isSubRegister(Reg, *ImpDefs)))
return true;
return false;
}

/// Return true if this instruction defines the specified physical
/// register, either explicitly or implicitly.
bool hasDefOfPhysReg(const MCInst &MI, unsigned Reg,
const MCRegisterInfo &RI) const {
for (int i = 0, e = NumDefs; i != e; ++i)
if (MI.getOperand(i).isReg() &&
RI.isSubRegisterEq(Reg, MI.getOperand(i).getReg()))
return true;
return hasImplicitDefOfPhysReg(Reg, &RI);
}

/// getSchedClass - Return the scheduling class for this instruction. The
/// scheduling class is an index into the InstrItineraryData table. This
/// returns zero if there is no known scheduling information for the
Expand Down
8 changes: 8 additions & 0 deletions include/llvm/MC/MCRegisterInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ class MCRegisterInfo {
const MCRegisterDesc *Desc; // Pointer to the descriptor array
unsigned NumRegs; // Number of entries in the array
unsigned RAReg; // Return address register
unsigned PCReg; // Program counter register
const MCRegisterClass *Classes; // Pointer to the regclass array
unsigned NumClasses; // Number of entries in the array
unsigned NumRegUnits; // Number of regunits.
Expand Down Expand Up @@ -232,6 +233,7 @@ class MCRegisterInfo {
/// InitMCRegisterInfo - Initialize MCRegisterInfo, called by TableGen
/// auto-generated routines. *DO NOT USE*.
void InitMCRegisterInfo(const MCRegisterDesc *D, unsigned NR, unsigned RA,
unsigned PC,
const MCRegisterClass *C, unsigned NC,
const uint16_t (*RURoots)[2],
unsigned NRU,
Expand All @@ -243,6 +245,7 @@ class MCRegisterInfo {
Desc = D;
NumRegs = NR;
RAReg = RA;
PCReg = PC;
Classes = C;
DiffLists = DL;
RegStrings = Strings;
Expand Down Expand Up @@ -297,6 +300,11 @@ class MCRegisterInfo {
return RAReg;
}

/// Return the register which is the program counter.
unsigned getProgramCounter() const {
return PCReg;
}

const MCRegisterDesc &operator[](unsigned RegNo) const {
assert(RegNo < NumRegs &&
"Attempting to access record for invalid register number!");
Expand Down
2 changes: 1 addition & 1 deletion lib/Target/ARM/ARMBaseRegisterInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ using namespace llvm;

ARMBaseRegisterInfo::ARMBaseRegisterInfo(const ARMBaseInstrInfo &tii,
const ARMSubtarget &sti)
: ARMGenRegisterInfo(ARM::LR), TII(tii), STI(sti),
: ARMGenRegisterInfo(ARM::LR, 0, 0, ARM::PC), TII(tii), STI(sti),
FramePtr((STI.isTargetDarwin() || STI.isThumb()) ? ARM::R7 : ARM::R11),
BasePtr(ARM::R6) {
}
Expand Down
2 changes: 1 addition & 1 deletion lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ static MCInstrInfo *createARMMCInstrInfo() {

static MCRegisterInfo *createARMMCRegisterInfo(StringRef Triple) {
MCRegisterInfo *X = new MCRegisterInfo();
InitARMMCRegisterInfo(X, ARM::LR);
InitARMMCRegisterInfo(X, ARM::LR, 0, 0, ARM::PC);
return X;
}

Expand Down
3 changes: 2 additions & 1 deletion lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,8 @@ static MCRegisterInfo *createX86MCRegisterInfo(StringRef TT) {
MCRegisterInfo *X = new MCRegisterInfo();
InitX86MCRegisterInfo(X, RA,
X86_MC::getDwarfRegFlavour(TT, false),
X86_MC::getDwarfRegFlavour(TT, true));
X86_MC::getDwarfRegFlavour(TT, true),
RA);
X86_MC::InitLLVM2SEHRegisterMapping(X);
return X;
}
Expand Down
8 changes: 5 additions & 3 deletions lib/Target/X86/X86RegisterInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,12 @@ EnableBasePointer("x86-use-base-pointer", cl::Hidden, cl::init(true),

X86RegisterInfo::X86RegisterInfo(X86TargetMachine &tm,
const TargetInstrInfo &tii)
: X86GenRegisterInfo(tm.getSubtarget<X86Subtarget>().is64Bit()
? X86::RIP : X86::EIP,
: X86GenRegisterInfo((tm.getSubtarget<X86Subtarget>().is64Bit()
? X86::RIP : X86::EIP),
X86_MC::getDwarfRegFlavour(tm.getTargetTriple(), false),
X86_MC::getDwarfRegFlavour(tm.getTargetTriple(), true)),
X86_MC::getDwarfRegFlavour(tm.getTargetTriple(), true),
(tm.getSubtarget<X86Subtarget>().is64Bit()
? X86::RIP : X86::EIP)),
TM(tm), TII(tii) {
X86_MC::InitLLVM2SEHRegisterMapping(this);

Expand Down
10 changes: 5 additions & 5 deletions utils/TableGen/RegisterInfoEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -921,9 +921,9 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
// MCRegisterInfo initialization routine.
OS << "static inline void Init" << TargetName
<< "MCRegisterInfo(MCRegisterInfo *RI, unsigned RA, "
<< "unsigned DwarfFlavour = 0, unsigned EHFlavour = 0) {\n"
<< "unsigned DwarfFlavour = 0, unsigned EHFlavour = 0, unsigned PC = 0) {\n"
<< " RI->InitMCRegisterInfo(" << TargetName << "RegDesc, "
<< Regs.size()+1 << ", RA, " << TargetName << "MCRegisterClasses, "
<< Regs.size()+1 << ", RA, PC, " << TargetName << "MCRegisterClasses, "
<< RegisterClasses.size() << ", "
<< TargetName << "RegUnitRoots, "
<< RegBank.getNumNativeRegUnits() << ", "
Expand Down Expand Up @@ -958,7 +958,7 @@ RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, CodeGenTarget &Target,

OS << "struct " << ClassName << " : public TargetRegisterInfo {\n"
<< " explicit " << ClassName
<< "(unsigned RA, unsigned D = 0, unsigned E = 0);\n"
<< "(unsigned RA, unsigned D = 0, unsigned E = 0, unsigned PC = 0);\n"
<< " virtual bool needsStackRealignment(const MachineFunction &) const\n"
<< " { return false; }\n";
if (!RegBank.getSubRegIndices().empty()) {
Expand Down Expand Up @@ -1267,12 +1267,12 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
EmitRegMappingTables(OS, Regs, true);

OS << ClassName << "::\n" << ClassName
<< "(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour)\n"
<< "(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour, unsigned PC)\n"
<< " : TargetRegisterInfo(" << TargetName << "RegInfoDesc"
<< ", RegisterClasses, RegisterClasses+" << RegisterClasses.size() <<",\n"
<< " SubRegIndexNameTable, SubRegIndexLaneMaskTable) {\n"
<< " InitMCRegisterInfo(" << TargetName << "RegDesc, "
<< Regs.size()+1 << ", RA,\n " << TargetName
<< Regs.size()+1 << ", RA, PC,\n " << TargetName
<< "MCRegisterClasses, " << RegisterClasses.size() << ",\n"
<< " " << TargetName << "RegUnitRoots,\n"
<< " " << RegBank.getNumNativeRegUnits() << ",\n"
Expand Down

0 comments on commit fbf3b4a

Please sign in to comment.