Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions clang/docs/ClangCommandLineReference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3423,6 +3423,10 @@ Enable MT ASE (MIPS only)

.. option:: -mxgot, -mno-xgot

Disable jump table optimization (nanoMIPS only)

.. option:: -mjump-table-opt, -mno-jump-table-opt

PowerPC
-------
.. option:: -maltivec, -mno-altivec
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -3485,6 +3485,8 @@ def mmicromips : Flag<["-"], "mmicromips">, Group<m_mips_Features_Group>;
def mno_micromips : Flag<["-"], "mno-micromips">, Group<m_mips_Features_Group>;
def mxgot : Flag<["-"], "mxgot">, Group<m_mips_Features_Group>;
def mno_xgot : Flag<["-"], "mno-xgot">, Group<m_mips_Features_Group>;
def mjump_table_opt : Flag<["-"], "mjump-table-opt">, Group<m_mips_Features_Group>;
def mno_jump_table_opt : Flag<["-"], "mno-jump-table-opt">, Group<m_mips_Features_Group>;
def mldc1_sdc1 : Flag<["-"], "mldc1-sdc1">, Group<m_mips_Features_Group>;
def mno_ldc1_sdc1 : Flag<["-"], "mno-ldc1-sdc1">, Group<m_mips_Features_Group>;
def mcheck_zero_division : Flag<["-"], "mcheck-zero-division">,
Expand Down
1 change: 0 additions & 1 deletion clang/lib/CodeGen/BackendUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,6 @@ static bool initTargetOptions(DiagnosticsEngine &Diags,
Options.ValueTrackingVariableLocations =
CodeGenOpts.ValueTrackingVariableLocations;
Options.XRayOmitFunctionIndex = CodeGenOpts.XRayOmitFunctionIndex;

Options.MCOptions.SplitDwarfFile = CodeGenOpts.SplitDwarfFile;
Options.MCOptions.MCRelaxAll = CodeGenOpts.RelaxAll;
Options.MCOptions.MCSaveTempLabels = CodeGenOpts.SaveTempLabels;
Expand Down
8 changes: 8 additions & 0 deletions clang/lib/Driver/ToolChains/Arch/Mips.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,14 @@ void mips::getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple,
Features.push_back("-xgot");
}

if (Arg *A = Args.getLastArg(options::OPT_mjump_table_opt,
options::OPT_mno_jump_table_opt)) {
if (A->getOption().matches(options::OPT_mno_jump_table_opt))
Features.push_back("+disable-jump-table-opt");
else
Features.push_back("-disable-jump-table-opt");
}

mips::FloatABI FloatABI = mips::getMipsFloatABI(D, Args, Triple);
if (FloatABI == mips::FloatABI::Soft) {
// FIXME: Note, this is a hack. We need to pass the selected float
Expand Down
1 change: 0 additions & 1 deletion clang/lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1921,7 +1921,6 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
<< "-fdiagnostics-hotness-threshold=";
}
}

// If the user requested to use a sample profile for PGO, then the
// backend will need to track source location information so the profile
// can be incorporated into the IR.
Expand Down
4 changes: 2 additions & 2 deletions llvm/include/llvm/CodeGen/CommandFlags.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,8 @@ bool getXRayOmitFunctionIndex();

bool getDebugStrictDwarf();

/// Create this object with static storage to register codegen-related command
/// line options.
/// Create this object with static storage to register codegen-related
/// command line options.
struct RegisterCodeGenFlags {
RegisterCodeGenFlags();
};
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/Mips/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ add_llvm_target(MipsCodeGen
MipsTargetMachine.cpp
MipsTargetObjectFile.cpp
MicroMipsSizeReduction.cpp
NanoMipsCompressJumpTables.cpp
NanoMipsLoadStoreOptimizer.cpp
NanoMipsMoveOptimizer.cpp
NanoMipsRegisterReAllocation.cpp
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/Mips/Mips.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ namespace llvm {
FunctionPass *createMicroMipsSizeReducePass();
FunctionPass *createMipsExpandPseudoPass();
FunctionPass *createMipsPreLegalizeCombiner();
FunctionPass *createNanoMipsCompressJumpTablesPass();
FunctionPass *createNanoMipsLoadStoreOptimizerPass();
FunctionPass *createNanoMipsMoveOptimizerPass();
FunctionPass *createNanoMipsRegisterReAllocationPass();
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/Mips/Mips.td
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,9 @@ def FeatureLongCalls : SubtargetFeature<"long-calls", "UseLongCalls", "true",
def FeatureXGOT
: SubtargetFeature<"xgot", "UseXGOT", "true", "Assume 32-bit GOT">;

def FeatureUseAbsoluteJumpTables
: SubtargetFeature<"disable-jump-table-opt", "UseAbsoluteJumpTables", "true", "Disable jump table optimization, use absolute jump tables instead">;

def FeatureUseIndirectJumpsHazard : SubtargetFeature<"use-indirect-jump-hazard",
"UseIndirectJumpsHazard",
"true", "Use indirect jump"
Expand Down
135 changes: 135 additions & 0 deletions llvm/lib/Target/Mips/MipsAsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include <cassert>
#include <cstdint>
#include <map>
Expand All @@ -71,6 +72,56 @@ using namespace llvm;

extern cl::opt<bool> EmitJalrReloc;

void MipsAsmPrinter::emitJumpTableInfo() {
if (!Subtarget->hasNanoMips() || Subtarget->useAbsoluteJumpTables() ) {
AsmPrinter::emitJumpTableInfo();
return;
}

const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
if (!MJTI)
return;

const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
if (JT.empty())
return;

const Function &F = MF->getFunction();
const TargetLoweringObjectFile &TLOF = getObjFileLowering();

MCSection *ReadOnlySection = TLOF.getSectionForJumpTable(F, TM);
OutStreamer->SwitchSection(ReadOnlySection);

auto MFI = MF->getInfo<MipsFunctionInfo>();
for (unsigned JTI = 0, e = JT.size(); JTI != e; ++JTI) {
const std::vector<MachineBasicBlock *> &JTBBs = JT[JTI].MBBs;

// If this jump table was deleted, ignore it.
if (JTBBs.empty())
continue;

unsigned EntrySize = MFI->getJumpTableEntrySize(JTI);
bool Signed = MFI->getJumpTableIsSigned(JTI);
emitJumpTableDir(*OutStreamer, EntrySize, JTBBs.size(), Signed);
emitAlignment(Align(EntrySize));
OutStreamer->emitLabel(GetJTISymbol(JTI));

MCSymbol *DiffLbl = MFI->getJumpTableSymbol(JTI);
for (auto *JTBB : JTBBs) {
const MCExpr *Value =
MCSymbolRefExpr::create(JTBB->getSymbol(), OutContext);
const MCExpr *DiffExpr = MCSymbolRefExpr::create(DiffLbl, OutContext);

// Each entry is:
// .byte/.hword/... (LBB - LBR) >> 1
Value = MCBinaryExpr::createSub(Value, DiffExpr, OutContext);
Value = MCBinaryExpr::createLShr(
Value, MCConstantExpr::create(1, OutContext), OutContext);
OutStreamer->emitValue(Value, EntrySize);
}
}
}

MipsTargetStreamer &MipsAsmPrinter::getTargetStreamer() const {
return static_cast<MipsTargetStreamer &>(*OutStreamer->getTargetStreamer());
}
Expand All @@ -79,6 +130,7 @@ bool MipsAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
Subtarget = &MF.getSubtarget<MipsSubtarget>();

MipsFI = MF.getInfo<MipsFunctionInfo>();
MFI = MF.getInfo<MipsFunctionInfo>();
if (Subtarget->inMips16Mode())
for (std::map<
const char *,
Expand Down Expand Up @@ -153,6 +205,79 @@ void MipsAsmPrinter::emitPseudoIndirectBranch(MCStreamer &OutStreamer,
EmitToStreamer(OutStreamer, TmpInst0);
}

void MipsAsmPrinter::emitJumpTableDest(MCStreamer &OutStreamer,
const MachineInstr *MI) {
Register DestReg = MI->getOperand(0).getReg();
Register TableReg = MI->getOperand(1).getReg();
Register EntryReg = MI->getOperand(2).getReg();
int JTIdx = MI->getOperand(3).getIndex();
unsigned Size = MFI->getJumpTableEntrySize(JTIdx);
unsigned Signed = MFI->getJumpTableIsSigned(JTIdx) ? 1 : 0;

// Mark each load instruction that loads from the table with a
// R_NANOMIPS_JUMPTABLE_LOAD relocation, referring to the start of the table.
MCSymbol *JTLabel = MF->getJTISymbol(JTIdx, OutContext);
MCSymbol *OffsetLabel = OutContext.createTempSymbol();
const MCExpr *OffsetExpr = MCSymbolRefExpr::create(OffsetLabel, OutContext);
const MCExpr *JTLabelExpr = MCSymbolRefExpr::create(JTLabel, OutContext);
OutStreamer.emitRelocDirective(*OffsetExpr, "R_NANOMIPS_JUMPTABLE_LOAD",
JTLabelExpr, SMLoc(),
*TM.getMCSubtargetInfo());
OutStreamer.emitLabel(OffsetLabel);

MCInst LoadI;
// Choose appropriate load instruction based on the entry size and signess.
switch (Size) {
case 1:
LoadI.setOpcode(Signed ? Mips::LBX_NM : Mips::LBUX_NM);
break;
case 2:
LoadI.setOpcode(Signed ? Mips::LHXS_NM : Mips::LHUXS_NM);
break;
case 4:
LoadI.setOpcode(Mips::LWXS_NM);
break;

default:
llvm_unreachable("unallowed jump table entry size");
break;
}

LoadI.addOperand(MCOperand::createReg(DestReg));
LoadI.addOperand(MCOperand::createReg(TableReg));
LoadI.addOperand(MCOperand::createReg(EntryReg));
EmitToStreamer(OutStreamer, LoadI);
}

// Each table starts with the following directive:
//
// .jumptable esize, nsize [, unsigned]
//
// esize: size of each element 8/16/32
// nsize: number of elements in table
// unsigned: optional token, assume signed if not specified.
void MipsAsmPrinter::emitJumpTableDir(MCStreamer &OutStreamer,
unsigned int EntrySize,
unsigned int EntryNum, bool Signed) {
auto JTDir = Twine(".jumptable ");
OutStreamer.emitRawText(JTDir.concat(std::to_string(EntrySize))
.concat(",")
.concat(std::to_string(EntryNum))
.concat(Signed ? "" : ",1"));
}

void MipsAsmPrinter::emitBrsc(MCStreamer &OutStreamer, const MachineInstr *MI) {
int JTIdx = MI->getOperand(1).getIndex();
int Size = MFI->getJumpTableEntrySize(JTIdx);
bool Signed = MFI->getJumpTableIsSigned(JTIdx);
MCSymbol *BRSCLabel = OutContext.createTempSymbol("BRSC");
MCInst TmpInst0;
MCInstLowering.Lower(MI, TmpInst0);
EmitToStreamer(OutStreamer, TmpInst0);
OutStreamer.emitLabel(BRSCLabel);
MFI->setJumpTableEntryInfo(JTIdx, Size, BRSCLabel, Signed);
}

// If there is an MO_JALR operand, insert:
//
// .reloc tmplabel, R_{MICRO}MIPS_JALR, symbol
Expand Down Expand Up @@ -275,6 +400,16 @@ void MipsAsmPrinter::emitInstruction(const MachineInstr *MI) {
continue;
}

if (Subtarget->hasNanoMips() &&
(I->getOpcode() == Mips::LoadJumpTableOffset)) {
emitJumpTableDest(*OutStreamer, &*I);
continue;
}

if (Subtarget->hasNanoMips() && I->getOpcode() == Mips::BRSC_NM) {
emitBrsc(*OutStreamer, &*I);
continue;
}
// The inMips16Mode() test is not permanent.
// Some instructions are marked as pseudo right now which
// would make the test fail for the wrong reason but
Expand Down
11 changes: 11 additions & 0 deletions llvm/lib/Target/Mips/MipsAsmPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,15 @@ class LLVM_LIBRARY_VISIBILITY MipsAsmPrinter : public AsmPrinter {
void emitPseudoIndirectBranch(MCStreamer &OutStreamer,
const MachineInstr *MI);

void emitJumpTableDest(MCStreamer &OutStreamer, const MachineInstr *MI);

// Emit brsc instruction followed by a label that will be used while creating
// offset expressions in jump table entries.
void emitBrsc(MCStreamer &OutStreamer, const MachineInstr *MI);

void emitJumpTableDir(MCStreamer &OutStreamer, unsigned int EntrySize,
unsigned int EntryNum, bool Signed);

// lowerOperand - Convert a MachineOperand into the equivalent MCOperand.
bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp);

Expand Down Expand Up @@ -116,6 +125,7 @@ class LLVM_LIBRARY_VISIBILITY MipsAsmPrinter : public AsmPrinter {
public:
const MipsSubtarget *Subtarget;
const MipsFunctionInfo *MipsFI;
MipsFunctionInfo *MFI;
MipsMCInstLower MCInstLowering;

explicit MipsAsmPrinter(TargetMachine &TM,
Expand Down Expand Up @@ -158,6 +168,7 @@ class LLVM_LIBRARY_VISIBILITY MipsAsmPrinter : public AsmPrinter {
void emitEndOfAsmFile(Module &M) override;
void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS);
void emitDebugValue(const MCExpr *Value, unsigned Size) const override;
void emitJumpTableInfo() override;
};

} // end namespace llvm
Expand Down
26 changes: 25 additions & 1 deletion llvm/lib/Target/Mips/MipsISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const {
case MipsISD::PCKEV: return "MipsISD::PCKEV";
case MipsISD::PCKOD: return "MipsISD::PCKOD";
case MipsISD::INSVE: return "MipsISD::INSVE";
case MipsISD::BR_JT: return "MipsISD::BR_JT";
}
return nullptr;
}
Expand Down Expand Up @@ -349,7 +350,10 @@ MipsTargetLowering::MipsTargetLowering(const MipsTargetMachine &TM,
AddPromotedToType(ISD::SETCC, MVT::i1, MVT::i32);

// Mips Custom Operations
setOperationAction(ISD::BR_JT, MVT::Other, Expand);
if (Subtarget.hasNanoMips() && !STI.useAbsoluteJumpTables())
setOperationAction(ISD::BR_JT, MVT::Other, Custom);
else
setOperationAction(ISD::BR_JT, MVT::Other, Expand);
setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
setOperationAction(ISD::BlockAddress, MVT::i32, Custom);
setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom);
Expand Down Expand Up @@ -1507,6 +1511,7 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) const
case ISD::GlobalAddress: return lowerGlobalAddress(Op, DAG);
case ISD::BlockAddress: return lowerBlockAddress(Op, DAG);
case ISD::GlobalTLSAddress: return lowerGlobalTLSAddress(Op, DAG);
case ISD::BR_JT: return lowerBR_JT(Op, DAG);
case ISD::JumpTable: return lowerJumpTable(Op, DAG);
case ISD::SELECT: return lowerSELECT(Op, DAG);
case ISD::SETCC: return lowerSETCC(Op, DAG);
Expand Down Expand Up @@ -2527,6 +2532,25 @@ lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const
return DAG.getNode(ISD::ADD, DL, PtrVT, ThreadPointer, Offset);
}

SDValue MipsTargetLowering::
lowerBR_JT(SDValue Op, SelectionDAG &DAG) const {
SDLoc DL(Op);
SDValue Chain = Op.getOperand(0);
SDValue JT = Op.getOperand(1);
SDValue Entry = Op.getOperand(2);

int JTI = cast<JumpTableSDNode>(JT.getNode())->getIndex();
auto *MFI = DAG.getMachineFunction().getInfo<MipsFunctionInfo>();
MFI->setJumpTableEntryInfo(JTI, 4, nullptr);

SDValue TJT = DAG.getTargetJumpTable(JTI, MVT::i32);
SDNode *Dest =
DAG.getMachineNode(Mips::LoadJumpTableOffset, DL, MVT::i32, JT, Entry, TJT);
return DAG.getNode(MipsISD::BR_JT, DL, MVT::Other, Chain, SDValue(Dest, 0),
TJT);
}


SDValue MipsTargetLowering::
lowerJumpTable(SDValue Op, SelectionDAG &DAG) const
{
Expand Down
6 changes: 5 additions & 1 deletion llvm/lib/Target/Mips/MipsISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,10 @@ class TargetRegisterClass;
UALW,
UALH,
UASW,
UASH
UASH,

// nanoMIPS br_jt.
BR_JT
};

} // ene namespace MipsISD
Expand Down Expand Up @@ -548,6 +551,7 @@ class TargetRegisterClass;
SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerBR_JT(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerSELECT(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerSETCC(SDValue Op, SelectionDAG &DAG) const;
Expand Down
Loading