Skip to content

Commit

Permalink
[RISCV] Merge RISCVMCInstLower.cpp into RISCVAsmPrinter.cpp.
Browse files Browse the repository at this point in the history
The separation here doesn't make much sense. I think it's a
leftover from the creation of the MC layer that has been
replicated to new targets.

By merging them we can avoid passing the AsmPrinter to the
MCInstLowering functions. We can make them member functions instead.

I think we can still do more integration of lowerSymbolOperand
and lowerRISCVVMachineInstrToMCInst, but I wanted to get feedback
on the direction first.

Reviewed By: asb, barannikov88

Differential Revision: https://reviews.llvm.org/D152311
  • Loading branch information
topperc committed Jun 12, 2023
1 parent 80fe316 commit 11e5a0d
Show file tree
Hide file tree
Showing 4 changed files with 236 additions and 270 deletions.
1 change: 0 additions & 1 deletion llvm/lib/Target/RISCV/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ add_llvm_target(RISCVCodeGen
RISCVISelLowering.cpp
RISCVMachineFunctionInfo.cpp
RISCVMacroFusion.cpp
RISCVMCInstLower.cpp
RISCVMergeBaseOffset.cpp
RISCVOptWInstrs.cpp
RISCVRedundantCopyElimination.cpp
Expand Down
5 changes: 0 additions & 5 deletions llvm/lib/Target/RISCV/RISCV.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,6 @@ class RISCVTargetMachine;
FunctionPass *createRISCVCodeGenPreparePass();
void initializeRISCVCodeGenPreparePass(PassRegistry &);

bool lowerRISCVMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
AsmPrinter &AP);
bool lowerRISCVMachineOperandToMCOperand(const MachineOperand &MO,
MCOperand &MCOp, const AsmPrinter &AP);

FunctionPass *createRISCVISelDag(RISCVTargetMachine &TM,
CodeGenOpt::Level OptLevel);

Expand Down
242 changes: 236 additions & 6 deletions llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,7 @@ class RISCVAsmPrinter : public AsmPrinter {
void EmitHwasanMemaccessSymbols(Module &M);

// Wrapper needed for tblgenned pseudo lowering.
bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const {
return lowerRISCVMachineOperandToMCOperand(MO, MCOp, *this);
}
bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const;

void emitStartOfAsmFile(Module &M) override;
void emitEndOfAsmFile(Module &M) override;
Expand All @@ -87,6 +85,8 @@ class RISCVAsmPrinter : public AsmPrinter {
void emitAttributes();

void emitNTLHint(const MachineInstr *MI);

bool lowerToMCInst(const MachineInstr *MI, MCInst &OutMI);
};
}

Expand Down Expand Up @@ -156,9 +156,9 @@ void RISCVAsmPrinter::emitInstruction(const MachineInstr *MI) {
return;
}

MCInst TmpInst;
if (!lowerRISCVMachineInstrToMCInst(MI, TmpInst, *this))
EmitToStreamer(*OutStreamer, TmpInst);
MCInst OutInst;
if (!lowerToMCInst(MI, OutInst))
EmitToStreamer(*OutStreamer, OutInst);
}

bool RISCVAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
Expand Down Expand Up @@ -510,3 +510,233 @@ void RISCVAsmPrinter::EmitHwasanMemaccessSymbols(Module &M) {
MCSTI);
}
}

static MCOperand lowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym,
const AsmPrinter &AP) {
MCContext &Ctx = AP.OutContext;
RISCVMCExpr::VariantKind Kind;

switch (MO.getTargetFlags()) {
default:
llvm_unreachable("Unknown target flag on GV operand");
case RISCVII::MO_None:
Kind = RISCVMCExpr::VK_RISCV_None;
break;
case RISCVII::MO_CALL:
Kind = RISCVMCExpr::VK_RISCV_CALL;
break;
case RISCVII::MO_PLT:
Kind = RISCVMCExpr::VK_RISCV_CALL_PLT;
break;
case RISCVII::MO_LO:
Kind = RISCVMCExpr::VK_RISCV_LO;
break;
case RISCVII::MO_HI:
Kind = RISCVMCExpr::VK_RISCV_HI;
break;
case RISCVII::MO_PCREL_LO:
Kind = RISCVMCExpr::VK_RISCV_PCREL_LO;
break;
case RISCVII::MO_PCREL_HI:
Kind = RISCVMCExpr::VK_RISCV_PCREL_HI;
break;
case RISCVII::MO_GOT_HI:
Kind = RISCVMCExpr::VK_RISCV_GOT_HI;
break;
case RISCVII::MO_TPREL_LO:
Kind = RISCVMCExpr::VK_RISCV_TPREL_LO;
break;
case RISCVII::MO_TPREL_HI:
Kind = RISCVMCExpr::VK_RISCV_TPREL_HI;
break;
case RISCVII::MO_TPREL_ADD:
Kind = RISCVMCExpr::VK_RISCV_TPREL_ADD;
break;
case RISCVII::MO_TLS_GOT_HI:
Kind = RISCVMCExpr::VK_RISCV_TLS_GOT_HI;
break;
case RISCVII::MO_TLS_GD_HI:
Kind = RISCVMCExpr::VK_RISCV_TLS_GD_HI;
break;
}

const MCExpr *ME =
MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Ctx);

if (!MO.isJTI() && !MO.isMBB() && MO.getOffset())
ME = MCBinaryExpr::createAdd(
ME, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);

if (Kind != RISCVMCExpr::VK_RISCV_None)
ME = RISCVMCExpr::create(ME, Kind, Ctx);
return MCOperand::createExpr(ME);
}

bool RISCVAsmPrinter::lowerOperand(const MachineOperand &MO,
MCOperand &MCOp) const {
switch (MO.getType()) {
default:
report_fatal_error("lowerOperand: unknown operand type");
case MachineOperand::MO_Register:
// Ignore all implicit register operands.
if (MO.isImplicit())
return false;
MCOp = MCOperand::createReg(MO.getReg());
break;
case MachineOperand::MO_RegisterMask:
// Regmasks are like implicit defs.
return false;
case MachineOperand::MO_Immediate:
MCOp = MCOperand::createImm(MO.getImm());
break;
case MachineOperand::MO_MachineBasicBlock:
MCOp = lowerSymbolOperand(MO, MO.getMBB()->getSymbol(), *this);
break;
case MachineOperand::MO_GlobalAddress:
MCOp = lowerSymbolOperand(MO, getSymbolPreferLocal(*MO.getGlobal()), *this);
break;
case MachineOperand::MO_BlockAddress:
MCOp = lowerSymbolOperand(MO, GetBlockAddressSymbol(MO.getBlockAddress()),
*this);
break;
case MachineOperand::MO_ExternalSymbol:
MCOp = lowerSymbolOperand(MO, GetExternalSymbolSymbol(MO.getSymbolName()),
*this);
break;
case MachineOperand::MO_ConstantPoolIndex:
MCOp = lowerSymbolOperand(MO, GetCPISymbol(MO.getIndex()), *this);
break;
case MachineOperand::MO_JumpTableIndex:
MCOp = lowerSymbolOperand(MO, GetJTISymbol(MO.getIndex()), *this);
break;
case MachineOperand::MO_MCSymbol:
MCOp = lowerSymbolOperand(MO, MO.getMCSymbol(), *this);
break;
}
return true;
}

static bool lowerRISCVVMachineInstrToMCInst(const MachineInstr *MI,
MCInst &OutMI) {
const RISCVVPseudosTable::PseudoInfo *RVV =
RISCVVPseudosTable::getPseudoInfo(MI->getOpcode());
if (!RVV)
return false;

OutMI.setOpcode(RVV->BaseInstr);

const MachineBasicBlock *MBB = MI->getParent();
assert(MBB && "MI expected to be in a basic block");
const MachineFunction *MF = MBB->getParent();
assert(MF && "MBB expected to be in a machine function");

const TargetRegisterInfo *TRI =
MF->getSubtarget<RISCVSubtarget>().getRegisterInfo();

assert(TRI && "TargetRegisterInfo expected");

uint64_t TSFlags = MI->getDesc().TSFlags;
unsigned NumOps = MI->getNumExplicitOperands();

// Skip policy, VL and SEW operands which are the last operands if present.
if (RISCVII::hasVecPolicyOp(TSFlags))
--NumOps;
if (RISCVII::hasVLOp(TSFlags))
--NumOps;
if (RISCVII::hasSEWOp(TSFlags))
--NumOps;

bool hasVLOutput = RISCV::isFaultFirstLoad(*MI);
for (unsigned OpNo = 0; OpNo != NumOps; ++OpNo) {
const MachineOperand &MO = MI->getOperand(OpNo);
// Skip vl ouput. It should be the second output.
if (hasVLOutput && OpNo == 1)
continue;

// Skip merge op. It should be the first operand after the result.
if (RISCVII::hasMergeOp(TSFlags) && OpNo == 1U + hasVLOutput) {
assert(MI->getNumExplicitDefs() == 1U + hasVLOutput);
continue;
}

MCOperand MCOp;
switch (MO.getType()) {
default:
llvm_unreachable("Unknown operand type");
case MachineOperand::MO_Register: {
Register Reg = MO.getReg();

if (RISCV::VRM2RegClass.contains(Reg) ||
RISCV::VRM4RegClass.contains(Reg) ||
RISCV::VRM8RegClass.contains(Reg)) {
Reg = TRI->getSubReg(Reg, RISCV::sub_vrm1_0);
assert(Reg && "Subregister does not exist");
} else if (RISCV::FPR16RegClass.contains(Reg)) {
Reg =
TRI->getMatchingSuperReg(Reg, RISCV::sub_16, &RISCV::FPR32RegClass);
assert(Reg && "Subregister does not exist");
} else if (RISCV::FPR64RegClass.contains(Reg)) {
Reg = TRI->getSubReg(Reg, RISCV::sub_32);
assert(Reg && "Superregister does not exist");
} else if (RISCV::VRN2M1RegClass.contains(Reg) ||
RISCV::VRN2M2RegClass.contains(Reg) ||
RISCV::VRN2M4RegClass.contains(Reg) ||
RISCV::VRN3M1RegClass.contains(Reg) ||
RISCV::VRN3M2RegClass.contains(Reg) ||
RISCV::VRN4M1RegClass.contains(Reg) ||
RISCV::VRN4M2RegClass.contains(Reg) ||
RISCV::VRN5M1RegClass.contains(Reg) ||
RISCV::VRN6M1RegClass.contains(Reg) ||
RISCV::VRN7M1RegClass.contains(Reg) ||
RISCV::VRN8M1RegClass.contains(Reg)) {
Reg = TRI->getSubReg(Reg, RISCV::sub_vrm1_0);
assert(Reg && "Subregister does not exist");
}

MCOp = MCOperand::createReg(Reg);
break;
}
case MachineOperand::MO_Immediate:
MCOp = MCOperand::createImm(MO.getImm());
break;
}
OutMI.addOperand(MCOp);
}

// Unmasked pseudo instructions need to append dummy mask operand to
// V instructions. All V instructions are modeled as the masked version.
if (RISCVII::hasDummyMaskOp(TSFlags))
OutMI.addOperand(MCOperand::createReg(RISCV::NoRegister));

return true;
}

bool RISCVAsmPrinter::lowerToMCInst(const MachineInstr *MI, MCInst &OutMI) {
if (lowerRISCVVMachineInstrToMCInst(MI, OutMI))
return false;

OutMI.setOpcode(MI->getOpcode());

for (const MachineOperand &MO : MI->operands()) {
MCOperand MCOp;
if (lowerOperand(MO, MCOp))
OutMI.addOperand(MCOp);
}

switch (OutMI.getOpcode()) {
case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
const Function &F = MI->getParent()->getParent()->getFunction();
if (F.hasFnAttribute("patchable-function-entry")) {
unsigned Num;
if (F.getFnAttribute("patchable-function-entry")
.getValueAsString()
.getAsInteger(10, Num))
return false;
emitNops(Num);
return true;
}
break;
}
}
return false;
}
Loading

0 comments on commit 11e5a0d

Please sign in to comment.