
FastISel may create a redundant BGTZ terminal which fallthroughes. ``` BGTZ %2:gpr32, %bb.1, implicit-def $at bb.1.bb1: ; predecessors: %bb.0 ``` The `!I->isBarrier()` check in MipsAsmPrinter::isBlockOnlyReachableByFallthrough will incorrectly not print a label, leading to a `Undefined temporary symbol ` error when we try assembling the output assembly file. See the updated `Fast-ISel/pr40325.ll` and https://github.com/rust-lang/rust/issues/108835 In addition, the `SwitchInst` condition is too conservative and prints many unneeded labels (see the updated tests). Just use the generic isBlockOnlyReachableByFallthrough, updated by commit 1995b9fead62f2f6c0ad217bd00ce3184f741fdb for SPARC, which also handles MIPS.
164 lines
5.9 KiB
C++
164 lines
5.9 KiB
C++
//===- MipsAsmPrinter.h - Mips LLVM Assembly Printer -----------*- C++ -*--===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Mips Assembly printer class.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_LIB_TARGET_MIPS_MIPSASMPRINTER_H
|
|
#define LLVM_LIB_TARGET_MIPS_MIPSASMPRINTER_H
|
|
|
|
#include "Mips16HardFloatInfo.h"
|
|
#include "MipsMCInstLower.h"
|
|
#include "MipsSubtarget.h"
|
|
#include "llvm/CodeGen/AsmPrinter.h"
|
|
#include "llvm/MC/MCStreamer.h"
|
|
#include "llvm/Support/Compiler.h"
|
|
#include <algorithm>
|
|
#include <map>
|
|
#include <memory>
|
|
|
|
namespace llvm {
|
|
|
|
class MCOperand;
|
|
class MCSubtargetInfo;
|
|
class MCSymbol;
|
|
class MachineBasicBlock;
|
|
class MachineConstantPool;
|
|
class MachineFunction;
|
|
class MachineInstr;
|
|
class MachineOperand;
|
|
class MipsFunctionInfo;
|
|
class MipsTargetStreamer;
|
|
class Module;
|
|
class raw_ostream;
|
|
class TargetMachine;
|
|
|
|
class LLVM_LIBRARY_VISIBILITY MipsAsmPrinter : public AsmPrinter {
|
|
MipsTargetStreamer &getTargetStreamer() const;
|
|
|
|
void EmitInstrWithMacroNoAT(const MachineInstr *MI);
|
|
|
|
//===------------------------------------------------------------------===//
|
|
// XRay implementation
|
|
//===------------------------------------------------------------------===//
|
|
|
|
public:
|
|
// XRay-specific lowering for Mips.
|
|
void LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI);
|
|
void LowerPATCHABLE_FUNCTION_EXIT(const MachineInstr &MI);
|
|
void LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI);
|
|
|
|
private:
|
|
/// MCP - Keep a pointer to constantpool entries of the current
|
|
/// MachineFunction.
|
|
const MachineConstantPool *MCP = nullptr;
|
|
|
|
/// InConstantPool - Maintain state when emitting a sequence of constant
|
|
/// pool entries so we can properly mark them as data regions.
|
|
bool InConstantPool = false;
|
|
|
|
std::map<const char *, const Mips16HardFloatInfo::FuncSignature *>
|
|
StubsNeeded;
|
|
|
|
void EmitSled(const MachineInstr &MI, SledKind Kind);
|
|
|
|
// tblgen'erated function.
|
|
bool emitPseudoExpansionLowering(MCStreamer &OutStreamer,
|
|
const MachineInstr *MI);
|
|
|
|
// Emit PseudoReturn, PseudoReturn64, PseudoIndirectBranch,
|
|
// and PseudoIndirectBranch64 as a JR, JR_MM, JALR, or JALR64 as appropriate
|
|
// for the target.
|
|
void emitPseudoIndirectBranch(MCStreamer &OutStreamer,
|
|
const MachineInstr *MI);
|
|
|
|
// lowerOperand - Convert a MachineOperand into the equivalent MCOperand.
|
|
bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp);
|
|
|
|
void emitInlineAsmStart() const override;
|
|
|
|
void emitInlineAsmEnd(const MCSubtargetInfo &StartInfo,
|
|
const MCSubtargetInfo *EndInfo) const override;
|
|
|
|
void EmitJal(const MCSubtargetInfo &STI, MCSymbol *Symbol);
|
|
|
|
void EmitInstrReg(const MCSubtargetInfo &STI, unsigned Opcode, unsigned Reg);
|
|
|
|
void EmitInstrRegReg(const MCSubtargetInfo &STI, unsigned Opcode,
|
|
unsigned Reg1, unsigned Reg2);
|
|
|
|
void EmitInstrRegRegReg(const MCSubtargetInfo &STI, unsigned Opcode,
|
|
unsigned Reg1, unsigned Reg2, unsigned Reg3);
|
|
|
|
void EmitMovFPIntPair(const MCSubtargetInfo &STI, unsigned MovOpc,
|
|
unsigned Reg1, unsigned Reg2, unsigned FPReg1,
|
|
unsigned FPReg2, bool LE);
|
|
|
|
void EmitSwapFPIntParams(const MCSubtargetInfo &STI,
|
|
Mips16HardFloatInfo::FPParamVariant, bool LE,
|
|
bool ToFP);
|
|
|
|
void EmitSwapFPIntRetval(const MCSubtargetInfo &STI,
|
|
Mips16HardFloatInfo::FPReturnVariant, bool LE);
|
|
|
|
void EmitFPCallStub(const char *, const Mips16HardFloatInfo::FuncSignature *);
|
|
|
|
void NaClAlignIndirectJumpTargets(MachineFunction &MF);
|
|
|
|
bool isLongBranchPseudo(int Opcode) const;
|
|
|
|
public:
|
|
const MipsSubtarget *Subtarget;
|
|
const MipsFunctionInfo *MipsFI;
|
|
MipsMCInstLower MCInstLowering;
|
|
|
|
explicit MipsAsmPrinter(TargetMachine &TM,
|
|
std::unique_ptr<MCStreamer> Streamer)
|
|
: AsmPrinter(TM, std::move(Streamer)), MCInstLowering(*this) {}
|
|
|
|
StringRef getPassName() const override { return "Mips Assembly Printer"; }
|
|
|
|
bool runOnMachineFunction(MachineFunction &MF) override;
|
|
|
|
void emitConstantPool() override {
|
|
bool UsingConstantPools =
|
|
(Subtarget->inMips16Mode() && Subtarget->useConstantIslands());
|
|
if (!UsingConstantPools)
|
|
AsmPrinter::emitConstantPool();
|
|
// we emit constant pools customly!
|
|
}
|
|
|
|
void emitInstruction(const MachineInstr *MI) override;
|
|
void printSavedRegsBitmask();
|
|
void emitFrameDirective();
|
|
const char *getCurrentABIString() const;
|
|
void emitFunctionEntryLabel() override;
|
|
void emitFunctionBodyStart() override;
|
|
void emitFunctionBodyEnd() override;
|
|
void emitBasicBlockEnd(const MachineBasicBlock &MBB) override;
|
|
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
|
|
const char *ExtraCode, raw_ostream &O) override;
|
|
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
|
|
const char *ExtraCode, raw_ostream &O) override;
|
|
void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
|
|
void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
|
|
void printMemOperandEA(const MachineInstr *MI, int opNum, raw_ostream &O);
|
|
void printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
|
|
const char *Modifier = nullptr);
|
|
void printRegisterList(const MachineInstr *MI, int opNum, raw_ostream &O);
|
|
void emitStartOfAsmFile(Module &M) override;
|
|
void emitEndOfAsmFile(Module &M) override;
|
|
void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS);
|
|
void emitDebugValue(const MCExpr *Value, unsigned Size) const override;
|
|
};
|
|
|
|
} // end namespace llvm
|
|
|
|
#endif // LLVM_LIB_TARGET_MIPS_MIPSASMPRINTER_H
|