From fa144fe6f348910c1ecb1cef98ccb8e4c6ba7ee1 Mon Sep 17 00:00:00 2001 From: Scott Brookes Date: Thu, 13 Jun 2019 16:10:28 -0400 Subject: [PATCH 01/14] 'upstreamable' (ie generic, non-ssith-specific) changes required to support SSITH/HOPE --- llvm/include/llvm/CodeGen/MachineInstr.h | 26 +++++++--- llvm/include/llvm/CodeGen/TargetInstrInfo.h | 6 ++- llvm/include/llvm/MC/MCInst.h | 29 +++++++++-- llvm/include/llvm/MC/MCObjectStreamer.h | 2 + llvm/include/llvm/MC/MCStreamer.h | 7 ++- llvm/include/llvm/MC/MCSymbol.h | 12 ++++- llvm/lib/CodeGen/MachineInstr.cpp | 22 +++++++- llvm/lib/CodeGen/PrologEpilogInserter.cpp | 5 +- llvm/lib/MC/MCELFStreamer.cpp | 2 + llvm/lib/MC/MCObjectStreamer.cpp | 5 ++ llvm/lib/MC/MCStreamer.cpp | 18 ++++++- .../RISCV/MCTargetDesc/RISCVELFStreamer.h | 12 ++--- llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp | 38 ++------------ llvm/lib/Target/RISCV/RISCVAsmPrinter.h | 50 +++++++++++++++++++ llvm/lib/Target/RISCV/RISCVFrameLowering.cpp | 13 +++-- llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 11 ++-- llvm/lib/Target/RISCV/RISCVInstrInfo.h | 6 ++- llvm/lib/Target/RISCV/RISCVMCInstLower.cpp | 2 + llvm/utils/TableGen/PseudoLoweringEmitter.cpp | 4 +- 19 files changed, 199 insertions(+), 71 deletions(-) create mode 100644 llvm/lib/Target/RISCV/RISCVAsmPrinter.h diff --git a/llvm/include/llvm/CodeGen/MachineInstr.h b/llvm/include/llvm/CodeGen/MachineInstr.h index 8c4d16419fa2..562313b45679 100644 --- a/llvm/include/llvm/CodeGen/MachineInstr.h +++ b/llvm/include/llvm/CodeGen/MachineInstr.h @@ -36,6 +36,7 @@ namespace llvm { +typedef uint32_t MachineInstrFlags_t; class AAResults; template class ArrayRef; class DIExpression; @@ -102,10 +103,23 @@ class MachineInstr // no unsigned wrap. NoSWrap = 1 << 12, // Instruction supports binary operator // no signed wrap. - IsExact = 1 << 13, // Instruction supports division is + IsExact = 1 << 13, // Instruction supports division is // known to be exact. NoFPExcept = 1 << 14, // Instruction does not raise // floatint-point exceptions. + FnProlog = 1 << 15, // Instruction is part of the compiler generated + // prolog + FnEpilog = 1 << 16, // Instruction is part of the compiler generated + // epilog + FPtrStore = 1 << 17, // Instruction writes a function pointer to memory + FPtrCreate = 1 << 18, // Instruction creates a function pointer + CallTarget = 1 << 19, // first instruction of a function + ReturnTarget = 1 << 20, // first instruction after a call + BranchTarget = 1 << 21, // a branch lands here. + IsCall = 1 << 22, + IsReturn = 1 << 23, + IsBranch = 1 << 24, + MaxFlagShift = 24 }; private: @@ -118,7 +132,7 @@ class MachineInstr using OperandCapacity = ArrayRecycler::Capacity; OperandCapacity CapOperands; // Capacity of the Operands array. - uint16_t Flags = 0; // Various bits of additional + MachineInstrFlags_t Flags = 0; // Various bits of additional // information about machine // instruction. @@ -304,7 +318,7 @@ class MachineInstr } /// Return the MI flags bitvector. - uint16_t getFlags() const { + MachineInstrFlags_t getFlags() const { return Flags; } @@ -315,7 +329,7 @@ class MachineInstr /// Set a MI flag. void setFlag(MIFlag Flag) { - Flags |= (uint16_t)Flag; + Flags |= (MachineInstrFlags_t)Flag; } void setFlags(unsigned flags) { @@ -326,7 +340,7 @@ class MachineInstr /// clearFlag - Clear a MI flag. void clearFlag(MIFlag Flag) { - Flags &= ~((uint16_t)Flag); + Flags &= ~((MachineInstrFlags_t)Flag); } /// Return true if MI is in a bundle (but not the first MI in a bundle). @@ -1632,7 +1646,7 @@ class MachineInstr /// Return the MIFlags which represent both MachineInstrs. This /// should be used when merging two MachineInstrs into one. This routine does /// not modify the MIFlags of this MachineInstr. - uint16_t mergeFlagsWith(const MachineInstr& Other) const; + MachineInstrFlags_t mergeFlagsWith(const MachineInstr& Other) const; static uint16_t copyFlagsFromInstruction(const Instruction &I); diff --git a/llvm/include/llvm/CodeGen/TargetInstrInfo.h b/llvm/include/llvm/CodeGen/TargetInstrInfo.h index 352965d8b20a..65471070a248 100644 --- a/llvm/include/llvm/CodeGen/TargetInstrInfo.h +++ b/llvm/include/llvm/CodeGen/TargetInstrInfo.h @@ -978,7 +978,8 @@ class TargetInstrInfo : public MCInstrInfo { MachineBasicBlock::iterator MI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const { + const TargetRegisterInfo *TRI, + unsigned flags = 0) const { llvm_unreachable("Target didn't implement " "TargetInstrInfo::storeRegToStackSlot!"); } @@ -990,7 +991,8 @@ class TargetInstrInfo : public MCInstrInfo { MachineBasicBlock::iterator MI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const { + const TargetRegisterInfo *TRI, + unsigned flags = 0) const { llvm_unreachable("Target didn't implement " "TargetInstrInfo::loadRegFromStackSlot!"); } diff --git a/llvm/include/llvm/MC/MCInst.h b/llvm/include/llvm/MC/MCInst.h index 360dbda58fcb..c9e2ce7c3d03 100644 --- a/llvm/include/llvm/MC/MCInst.h +++ b/llvm/include/llvm/MC/MCInst.h @@ -160,20 +160,41 @@ class MCInst { // These flags could be used to pass some info from one target subcomponent // to another, for example, from disassembler to asm printer. The values of // the flags have any sense on target level only (e.g. prefixes on x86). - unsigned Flags = 0; + enum : unsigned { NumFlagsBits = 31 }; + mutable uint32_t Flags : NumFlagsBits; SMLoc Loc; SmallVector Operands; public: + /// Get the (implementation defined) symbol flags. + uint32_t getFlags() const { return Flags; } + + /// Set the (implementation defined) symbol flags. + void setFlags(uint32_t Value) const { + assert(Value < (1U << NumFlagsBits) && "Out of range flags"); + Flags = Value; + } + + /// Modify the flags via a mask + void modifyFlags(uint32_t Value, uint32_t Mask) const { + assert(Value < (1U << NumFlagsBits) && "Out of range flags"); + Flags = (Flags & ~Mask) | Value; + } + + void setFlag(uint32_t Value) const { + modifyFlags(Value, 0); + } + + bool getFlag(uint32_t Flag) const { + return Flags & Flag; + } + MCInst() = default; void setOpcode(unsigned Op) { Opcode = Op; } unsigned getOpcode() const { return Opcode; } - void setFlags(unsigned F) { Flags = F; } - unsigned getFlags() const { return Flags; } - void setLoc(SMLoc loc) { Loc = loc; } SMLoc getLoc() const { return Loc; } diff --git a/llvm/include/llvm/MC/MCObjectStreamer.h b/llvm/include/llvm/MC/MCObjectStreamer.h index 9e3f87565e26..e483f48d600e 100644 --- a/llvm/include/llvm/MC/MCObjectStreamer.h +++ b/llvm/include/llvm/MC/MCObjectStreamer.h @@ -124,6 +124,8 @@ class MCObjectStreamer : public MCStreamer { void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override; void ChangeSection(MCSection *Section, const MCExpr *Subsection) override; void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override; + void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment) override; /// Emit an instruction to a special fragment, because this instruction /// can change its size during relaxation. diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h index d8e8dce02e88..c8aeebd775f1 100644 --- a/llvm/include/llvm/MC/MCStreamer.h +++ b/llvm/include/llvm/MC/MCStreamer.h @@ -102,6 +102,11 @@ class MCTargetStreamer { virtual void emitLabel(MCSymbol *Symbol); // Allow a target to add behavior to the emitAssignment of MCStreamer. virtual void emitAssignment(MCSymbol *Symbol, const MCExpr *Value); + // Allow a target to add behavior to the EmitInstruction of MCStreamer + virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI); + // Allow a target to add behavior or the EmitCommonSymbol of MCStreamer + virtual void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment); virtual void prettyPrintAsm(MCInstPrinter &InstPrinter, uint64_t Address, const MCInst &Inst, const MCSubtargetInfo &STI, @@ -592,7 +597,7 @@ class MCStreamer { /// \param ByteAlignment - The alignment of the symbol if /// non-zero. This must be a power of 2. virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, - unsigned ByteAlignment) = 0; + unsigned ByteAlignment); /// Emit a local common (.lcomm) symbol. /// diff --git a/llvm/include/llvm/MC/MCSymbol.h b/llvm/include/llvm/MC/MCSymbol.h index 84263bf94035..d445c2392ad3 100644 --- a/llvm/include/llvm/MC/MCSymbol.h +++ b/llvm/include/llvm/MC/MCSymbol.h @@ -121,7 +121,7 @@ class MCSymbol { /// The Flags field is used by object file implementations to store /// additional per symbol information which is not easily classified. - enum : unsigned { NumFlagsBits = 16 }; + enum : unsigned { NumFlagsBits = 31 }; mutable uint32_t Flags : NumFlagsBits; /// Index field, for use by the object file implementation. @@ -406,7 +406,6 @@ class MCSymbol { /// dump - Print the value to stderr. void dump() const; -protected: /// Get the (implementation defined) symbol flags. uint32_t getFlags() const { return Flags; } @@ -421,6 +420,15 @@ class MCSymbol { assert(Value < (1U << NumFlagsBits) && "Out of range flags"); Flags = (Flags & ~Mask) | Value; } + + void setFlag(uint32_t Value) const { + modifyFlags(Value, 0); + } + + bool getFlag(uint32_t Flag) const { + return Flags & Flag; + } + }; inline raw_ostream &operator<<(raw_ostream &OS, const MCSymbol &Sym) { diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp index 08d786f8f12c..2621551181ed 100644 --- a/llvm/lib/CodeGen/MachineInstr.cpp +++ b/llvm/lib/CodeGen/MachineInstr.cpp @@ -517,7 +517,7 @@ void MachineInstr::cloneInstrSymbols(MachineFunction &MF, setHeapAllocMarker(MF, MI.getHeapAllocMarker()); } -uint16_t MachineInstr::mergeFlagsWith(const MachineInstr &Other) const { +MachineInstrFlags_t MachineInstr::mergeFlagsWith(const MachineInstr &Other) const { // For now, the just return the union of the flags. If the flags get more // complicated over time, we might need more logic here. return getFlags() | Other.getFlags(); @@ -1540,6 +1540,26 @@ void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST, OS << "exact "; if (getFlag(MachineInstr::NoFPExcept)) OS << "nofpexcept "; + if (getFlag(MachineInstr::FnProlog)) + OS << "func-prolog "; + if (getFlag(MachineInstr::FnEpilog)) + OS << "func-epilog "; + if (getFlag(MachineInstr::FPtrStore)) + OS << "func-ptr-store "; + if (getFlag(MachineInstr::FPtrCreate)) + OS << "func-ptr-create "; + if (getFlag(MachineInstr::CallTarget)) + OS << "call-target "; + if (getFlag(MachineInstr::ReturnTarget)) + OS << "return-target "; + if (getFlag(MachineInstr::BranchTarget)) + OS << "branch-target "; + if (getFlag(MachineInstr::IsCall)) + OS << "is-call "; + if (getFlag(MachineInstr::IsReturn)) + OS << "is-return "; + if (getFlag(MachineInstr::IsBranch)) + OS << "is-branch "; // Print the opcode name. if (TII) diff --git a/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/llvm/lib/CodeGen/PrologEpilogInserter.cpp index d583643ac68f..4d2500f57d56 100644 --- a/llvm/lib/CodeGen/PrologEpilogInserter.cpp +++ b/llvm/lib/CodeGen/PrologEpilogInserter.cpp @@ -555,7 +555,7 @@ static void insertCSRSaves(MachineBasicBlock &SaveBlock, } else { const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); TII.storeRegToStackSlot(SaveBlock, I, Reg, true, CS.getFrameIdx(), RC, - TRI); + TRI, MachineInstr::FnProlog); } } } @@ -581,7 +581,8 @@ static void insertCSRRestores(MachineBasicBlock &RestoreBlock, .addReg(CI.getDstReg(), getKillRegState(true)); } else { const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); - TII.loadRegFromStackSlot(RestoreBlock, I, Reg, CI.getFrameIdx(), RC, TRI); + TII.loadRegFromStackSlot(RestoreBlock, I, Reg, CI.getFrameIdx(), RC, TRI, + MachineInstr::FnEpilog); assert(I != RestoreBlock.begin() && "loadRegFromStackSlot didn't insert any code!"); // Insert in reverse order. loadRegFromStackSlot can insert diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp index 0a0c30df9c07..2059b53805a7 100644 --- a/llvm/lib/MC/MCELFStreamer.cpp +++ b/llvm/lib/MC/MCELFStreamer.cpp @@ -291,6 +291,8 @@ void MCELFStreamer::EmitCommonSymbol(MCSymbol *S, uint64_t Size, auto *Symbol = cast(S); getAssembler().registerSymbol(*Symbol); + MCObjectStreamer::EmitCommonSymbol(S, Size, ByteAlignment); + if (!Symbol->isBindingSet()) { Symbol->setBinding(ELF::STB_GLOBAL); Symbol->setExternal(true); diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp index 3d1358df475f..dcd0fc075ce0 100644 --- a/llvm/lib/MC/MCObjectStreamer.cpp +++ b/llvm/lib/MC/MCObjectStreamer.cpp @@ -267,6 +267,11 @@ void MCObjectStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) { EmitLabel(Frame.End); } +void MCObjectStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment) { + MCStreamer::EmitCommonSymbol(Symbol, Size, ByteAlignment); +} + void MCObjectStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) { MCStreamer::EmitLabel(Symbol, Loc); diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp index 0ab883536779..9a67fe538bee 100644 --- a/llvm/lib/MC/MCStreamer.cpp +++ b/llvm/lib/MC/MCStreamer.cpp @@ -50,6 +50,11 @@ MCTargetStreamer::~MCTargetStreamer() = default; void MCTargetStreamer::emitLabel(MCSymbol *Symbol) {} +void MCTargetStreamer::emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) {} + +void MCTargetStreamer::emitCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment) {} + void MCTargetStreamer::finish() {} void MCTargetStreamer::changeSection(const MCSection *CurSection, @@ -397,6 +402,13 @@ void MCStreamer::AssignFragment(MCSymbol *Symbol, MCFragment *Fragment) { SymbolOrdering[Symbol] = 1 + SymbolOrdering.size(); } +void MCStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment) { + MCTargetStreamer *TS = getTargetStreamer(); + if (TS) + TS->emitCommonSymbol(Symbol, Size, ByteAlignment); +} + void MCStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) { Symbol->redefineIfPossible(); @@ -1012,11 +1024,15 @@ void MCStreamer::visitUsedExpr(const MCExpr &Expr) { } } -void MCStreamer::EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &) { +void MCStreamer::EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) { // Scan for values. for (unsigned i = Inst.getNumOperands(); i--;) if (Inst.getOperand(i).isExpr()) visitUsedExpr(*Inst.getOperand(i).getExpr()); + + MCTargetStreamer *TS = getTargetStreamer(); + if (TS) + TS->emitInstruction(Inst, STI); } void MCStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo, diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h index 138df786eaf3..1e39dd479d9d 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h @@ -19,12 +19,12 @@ class RISCVTargetELFStreamer : public RISCVTargetStreamer { MCELFStreamer &getStreamer(); RISCVTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI); - virtual void emitDirectiveOptionPush(); - virtual void emitDirectiveOptionPop(); - virtual void emitDirectiveOptionRVC(); - virtual void emitDirectiveOptionNoRVC(); - virtual void emitDirectiveOptionRelax(); - virtual void emitDirectiveOptionNoRelax(); + virtual void emitDirectiveOptionPush() override; + virtual void emitDirectiveOptionPop() override; + virtual void emitDirectiveOptionRVC() override; + virtual void emitDirectiveOptionNoRVC() override; + virtual void emitDirectiveOptionRelax() override; + virtual void emitDirectiveOptionNoRelax() override; }; } #endif diff --git a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp index f4aa28bcc0c1..871be10e8c1a 100644 --- a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp +++ b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp @@ -28,49 +28,19 @@ #include "llvm/MC/MCSymbol.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/raw_ostream.h" -using namespace llvm; - -#define DEBUG_TYPE "asm-printer" - -STATISTIC(RISCVNumInstrsCompressed, - "Number of RISC-V Compressed instructions emitted"); - -namespace { -class RISCVAsmPrinter : public AsmPrinter { -public: - explicit RISCVAsmPrinter(TargetMachine &TM, - std::unique_ptr Streamer) - : AsmPrinter(TM, std::move(Streamer)) {} - - StringRef getPassName() const override { return "RISCV Assembly Printer"; } - - void EmitInstruction(const MachineInstr *MI) override; - - bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, raw_ostream &OS) override; - bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, raw_ostream &OS) override; - - void EmitToStreamer(MCStreamer &S, const MCInst &Inst); - bool emitPseudoExpansionLowering(MCStreamer &OutStreamer, - const MachineInstr *MI); - - // Wrapper needed for tblgenned pseudo lowering. - bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const { - return LowerRISCVMachineOperandToMCOperand(MO, MCOp, *this); - } -}; -} +#include "RISCVAsmPrinter.h" #define GEN_COMPRESS_INSTR #include "RISCVGenCompressInstEmitter.inc" -void RISCVAsmPrinter::EmitToStreamer(MCStreamer &S, const MCInst &Inst) { +bool RISCVAsmPrinter::EmitToStreamer(MCStreamer &S, const MCInst &Inst) { MCInst CInst; bool Res = compressInst(CInst, Inst, *TM.getMCSubtargetInfo(), OutStreamer->getContext()); if (Res) ++RISCVNumInstrsCompressed; AsmPrinter::EmitToStreamer(*OutStreamer, Res ? CInst : Inst); + + return Res; } // Simple pseudo-instructions have their lowering (with expansion to real diff --git a/llvm/lib/Target/RISCV/RISCVAsmPrinter.h b/llvm/lib/Target/RISCV/RISCVAsmPrinter.h new file mode 100644 index 000000000000..24639644fe94 --- /dev/null +++ b/llvm/lib/Target/RISCV/RISCVAsmPrinter.h @@ -0,0 +1,50 @@ +//===-- RISCVAsmPrinter.h - Top-level interface RISCVAsmPrinter --*- 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 +// +//===----------------------------------------------------------------------===// +// +// This file contains the entry points and class definition for the +// RISCVAsmPrinter +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_RISCV_RISCVASMPRINTER_H +#define LLVM_LIB_TARGET_RISCV_RISCVASMPRINTER_H + +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/MC/MCInst.h" +#include "llvm/CodeGen/AsmPrinter.h" + +#define DEBUG_TYPE "asm-printer" + +using namespace llvm; + +class RISCVAsmPrinter : public AsmPrinter { +public: + explicit RISCVAsmPrinter(TargetMachine &TM, + std::unique_ptr Streamer) + : AsmPrinter(TM, std::move(Streamer)) {} + + StringRef getPassName() const override { return "RISCV Assembly Printer"; } + + void EmitInstruction(const MachineInstr *MI) override; + + bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, + const char *ExtraCode, raw_ostream &OS) override; + bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, + const char *ExtraCode, raw_ostream &OS) override; + + bool EmitToStreamer(MCStreamer &S, const MCInst &Inst); + bool emitPseudoExpansionLowering(MCStreamer &OutStreamer, + const MachineInstr *MI); + + // Wrapper needed for tblgenned pseudo lowering. + bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const { + return LowerRISCVMachineOperandToMCOperand(MO, MCOp, *this); + } +}; + +#endif diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp index c60fc3fc6b42..2bc1c716b22c 100644 --- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp @@ -144,7 +144,8 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF, StackSize = FirstSPAdjustAmount; // Allocate space on the stack if necessary. - adjustReg(MBB, MBBI, DL, SPReg, SPReg, -StackSize, MachineInstr::FrameSetup); + adjustReg(MBB, MBBI, DL, SPReg, SPReg, -StackSize, + (MachineInstr::MIFlag)(MachineInstr::FrameSetup | MachineInstr::FnProlog)); // Emit ".cfi_def_cfa_offset StackSize" unsigned CFIIndex = MF.addFrameInst( @@ -179,7 +180,8 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF, MF.getFunction(), "Frame pointer required, but has been reserved."}); adjustReg(MBB, MBBI, DL, FPReg, SPReg, - StackSize - RVFI->getVarArgsSaveSize(), MachineInstr::FrameSetup); + StackSize - RVFI->getVarArgsSaveSize(), + (MachineInstr::MIFlag)(MachineInstr::FrameSetup | MachineInstr::FnProlog)); // Emit ".cfi_def_cfa $fp, 0" unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createDefCfa( @@ -280,7 +282,7 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF, if (RI->needsStackRealignment(MF) || MFI.hasVarSizedObjects()) { assert(hasFP(MF) && "frame pointer should not have been eliminated"); adjustReg(MBB, LastFrameDestroy, DL, SPReg, FPReg, -FPOffset, - MachineInstr::FrameDestroy); + (MachineInstr::MIFlag)(MachineInstr::FrameDestroy | MachineInstr::FnEpilog)); } uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF); @@ -290,14 +292,15 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF, "SecondSPAdjustAmount should be greater than zero"); adjustReg(MBB, LastFrameDestroy, DL, SPReg, SPReg, SecondSPAdjustAmount, - MachineInstr::FrameDestroy); + (MachineInstr::MIFlag)(MachineInstr::FrameDestroy | MachineInstr::FnEpilog)); } if (FirstSPAdjustAmount) StackSize = FirstSPAdjustAmount; // Deallocate stack - adjustReg(MBB, MBBI, DL, SPReg, SPReg, StackSize, MachineInstr::FrameDestroy); + adjustReg(MBB, MBBI, DL, SPReg, SPReg, StackSize, + (MachineInstr::MIFlag)(MachineInstr::FrameDestroy | MachineInstr::FnEpilog)); } int RISCVFrameLowering::getFrameIndexReference(const MachineFunction &MF, diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp index ac8e0ab9ec13..ac55560198f4 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp @@ -114,7 +114,8 @@ void RISCVInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, Register SrcReg, bool IsKill, int FI, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const { + const TargetRegisterInfo *TRI, + unsigned flags) const { DebugLoc DL; if (I != MBB.end()) DL = I->getDebugLoc(); @@ -134,14 +135,16 @@ void RISCVInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, BuildMI(MBB, I, DL, get(Opcode)) .addReg(SrcReg, getKillRegState(IsKill)) .addFrameIndex(FI) - .addImm(0); + .addImm(0) + .setMIFlags(flags); } void RISCVInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, Register DstReg, int FI, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const { + const TargetRegisterInfo *TRI, + unsigned flags) const { DebugLoc DL; if (I != MBB.end()) DL = I->getDebugLoc(); @@ -158,7 +161,7 @@ void RISCVInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, else llvm_unreachable("Can't load this register from stack slot"); - BuildMI(MBB, I, DL, get(Opcode), DstReg).addFrameIndex(FI).addImm(0); + BuildMI(MBB, I, DL, get(Opcode), DstReg).addFrameIndex(FI).addImm(0).setMIFlags(flags); } void RISCVInstrInfo::movImm(MachineBasicBlock &MBB, diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.h b/llvm/lib/Target/RISCV/RISCVInstrInfo.h index f1f4e6573df8..8d9306069f52 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.h +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.h @@ -41,12 +41,14 @@ class RISCVInstrInfo : public RISCVGenInstrInfo { MachineBasicBlock::iterator MBBI, Register SrcReg, bool IsKill, int FrameIndex, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const override; + const TargetRegisterInfo *TRI, + unsigned flags = 0) const override; void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DstReg, int FrameIndex, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const override; + const TargetRegisterInfo *TRI, + unsigned flags = 0) const override; // Materializes the given integer Val into DstReg. void movImm(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, diff --git a/llvm/lib/Target/RISCV/RISCVMCInstLower.cpp b/llvm/lib/Target/RISCV/RISCVMCInstLower.cpp index b1dbcfa7f738..143cd9023d93 100644 --- a/llvm/lib/Target/RISCV/RISCVMCInstLower.cpp +++ b/llvm/lib/Target/RISCV/RISCVMCInstLower.cpp @@ -134,4 +134,6 @@ void llvm::LowerRISCVMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, if (LowerRISCVMachineOperandToMCOperand(MO, MCOp, AP)) OutMI.addOperand(MCOp); } + + OutMI.setFlags(MI->getFlags()); } diff --git a/llvm/utils/TableGen/PseudoLoweringEmitter.cpp b/llvm/utils/TableGen/PseudoLoweringEmitter.cpp index 3a80d8e5d1c4..519cb7cc647d 100644 --- a/llvm/utils/TableGen/PseudoLoweringEmitter.cpp +++ b/llvm/utils/TableGen/PseudoLoweringEmitter.cpp @@ -212,7 +212,9 @@ void PseudoLoweringEmitter::emitLoweringEmitter(raw_ostream &o) { << Source.TheDef->getName() << ": {\n" << " MCInst TmpInst;\n" << " MCOperand MCOp;\n" - << " TmpInst.setOpcode(" << Dest.Namespace << "::" + << " TmpInst.setFlags(MI->getFlags());\n" + << "\n" + << " TmpInst.setOpcode(" << Dest.Namespace << "::" << Dest.TheDef->getName() << ");\n"; // Copy the operands from the source instruction. From 3b15a1b23b20660c58a318b7003003201646aae9 Mon Sep 17 00:00:00 2001 From: Scott Brookes Date: Thu, 13 Jun 2019 16:47:17 -0400 Subject: [PATCH 02/14] SSITH/HOPE (also called ISP) tagging support --- llvm/include/llvm/MC/MCObjectFileInfo.h | 7 + llvm/include/llvm/MC/SSITHMetadata.h | 177 ++++++++++++++++++ llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 29 +-- llvm/lib/MC/MCObjectFileInfo.cpp | 9 + llvm/lib/Target/RISCV/CMakeLists.txt | 2 + llvm/lib/Target/RISCV/ISP.h | 54 ++++++ llvm/lib/Target/RISCV/ISPAsmPrinter.cpp | 99 ++++++++++ llvm/lib/Target/RISCV/ISPAsmPrinter.h | 19 ++ llvm/lib/Target/RISCV/ISPMetadataPass.cpp | 121 ++++++++++++ .../Target/RISCV/MCTargetDesc/CMakeLists.txt | 1 + .../RISCV/MCTargetDesc/ISPELFStreamer.cpp | 166 ++++++++++++++++ .../RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp | 4 +- llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp | 8 +- llvm/lib/Target/RISCV/RISCVTargetMachine.cpp | 5 + 14 files changed, 683 insertions(+), 18 deletions(-) create mode 100755 llvm/include/llvm/MC/SSITHMetadata.h create mode 100644 llvm/lib/Target/RISCV/ISP.h create mode 100644 llvm/lib/Target/RISCV/ISPAsmPrinter.cpp create mode 100644 llvm/lib/Target/RISCV/ISPAsmPrinter.h create mode 100644 llvm/lib/Target/RISCV/ISPMetadataPass.cpp create mode 100644 llvm/lib/Target/RISCV/MCTargetDesc/ISPELFStreamer.cpp diff --git a/llvm/include/llvm/MC/MCObjectFileInfo.h b/llvm/include/llvm/MC/MCObjectFileInfo.h index 18e77c4b3aff..e7d728256954 100644 --- a/llvm/include/llvm/MC/MCObjectFileInfo.h +++ b/llvm/include/llvm/MC/MCObjectFileInfo.h @@ -164,6 +164,9 @@ class MCObjectFileInfo { /// Remarks section. MCSection *RemarksSection = nullptr; + // ISP Metadata Section + MCSection *ISPMetadataSection; + /// EH frame section. /// /// It is initialized on demand so it can be overwritten (with uniquing). @@ -401,6 +404,10 @@ class MCObjectFileInfo { return EHFrameSection; } + MCSection *getISPMetadataSection() const { + return ISPMetadataSection; + } + enum Environment { IsMachO, IsELF, IsCOFF, IsWasm, IsXCOFF }; Environment getObjectFileType() const { return Env; } diff --git a/llvm/include/llvm/MC/SSITHMetadata.h b/llvm/include/llvm/MC/SSITHMetadata.h new file mode 100755 index 000000000000..99dc9d1c77f1 --- /dev/null +++ b/llvm/include/llvm/MC/SSITHMetadata.h @@ -0,0 +1,177 @@ +/* + * Copyright © 2017-2018 The Charles Stark Draper Laboratory, Inc. and/or Dover Microsystems, Inc. + * All rights reserved. + * + * Use and disclosure subject to the following license. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef METADATA_H +#define METADATA_H + +#define ISP_METADATA_ELF_SECTION_NAME ".dover_metadata" + +/* New metadata format in images: + +The goal with this format is to establish a smaller encoding, and a somewhat more general purpose +descriptive encoding. Ultimately, some of these fields will be uleb128 encoded, as soon as we +can figure out some tool bugs. For now, some of the uleb128 destined fields are fixed width. +We note these fields in the descriptions here for future notice. + +Metadata operations in the image now consist of a stream, with some operations being dependent +on data from previous operations. This is similar to DWARF debug information encoding. Code +which processes the metadata should process the stream of operations in order, changing +internal state as it goes. + +The first operation encountered in any metadata stream sets the current base address off which +subsequent operations should be based. + +DMD_SET_BASE_ADDRESS_OP (uleb128, but currently byte) +
(uintptr_t) + +Following the SET_BASE_ADDRESS operation, will be a sequence of zero or more other operations. +The SET_BASE_ADDRESS operation can appear multiple times. It just resets the current base +address value for interpretation of operations that follow it in the stream. + +DMD_TAG_ADDRESS_OP (uleb128, but currently byte) + (uleb128, but currently 32bits) + (uleb128, but currently byte) + +The TAG_ADDRESS operation causes a tag to be applied to a specific address. The address to be +tagged is formed by adding the field to the current base address. The + field names the tag to be applied to the resulting address. The specifier +is a known, stable constant specific to supported policies. The constant value is invariant +across minor revisions and builds of the operating kernel and policy code, to allow compiled +binaries to have some longevity. Tagging code will use this constant to look up the appropriate +runtime tag handle or value to apply to the address. + +DMD_TAG_ADDRESS_RANGE (uleb128, but currently byte) + (uleb128, but currently 32bits) + (uleb128, but currently 32bits) + (uleb128, but currently byte) + +The TAG_ADDRESS_RANGE operations causes a tag to be applied to a range of addresses. +The start and end address ranges are formed by taking their respective relative address +fields and adding them to the current base address. The field names +the tag to be applied to the resulting address, as per the TAG_ADDRESS operation. + +DMD_TAG_POLICY_SYMBOL (uleb128, but currently byte) + (asciiz) + (uleb128, but currently 32bits) + +DMD_TAG_POLICY_SYMBOL operations cause a symbol whose length can be determined from +a symbol table (e.g. ELF symbol table) to be tagged. The field is generated +by the policy tool, and is not the same as a tag specifier. Tag types are not stable, +and can and will change from build to build of policies. The symbol name is a null +terminated name. These records are generated by the policy tool, exclusively. + +DMD_TAG_POLICY_RANGE (uleb128, but currently byte) + (uintptr_t) + (uintptr_t) + (uleb128, but currently 32bits) + +DMD_TAG_POLICY_RANGE operations cause an address range to be tagged. The +field is generated by the policy tool, and is not the same as a tag specifier. +Tag types are not stable, and can and will change from build to build of policies. +These records are generated by the policy tool, exclusively. + +DMD_TAG_POLICY_SYMBOL_RANKED (uleb128, but currently byte) + (asciiz) + (uleb128, but currently 32bits) + (uleb128, but currently 32bits) + (uleb128, but currently 32bits) + +DMD_TAG_POLICY_SYMBOL_RANKED operations cause a symbol whose length can be determined from +a symbol table (e.g. ELF symbol table) to be tagged. The field is generated +by the policy tool, and is not the same as a tag specifier. Tag types are not stable, +and can and will change from build to build of policies. The symbol name is a null +terminated name. These records are generated by the policy tool, exclusively. +The tag category and rank fields are used to determine overrides of tags. A tag in +the same category as another with a higher rank will supercede a lower ranked tag +on any given address. + +DMD_TAG_POLICY_RANGE_RANKED (uleb128, but currently byte) + (uintptr_t) + (uintptr_t) + (uleb128, but currently 32bits) + (uleb128, but currently 32bits) + (uleb128, but currently 32bits) + +DMD_TAG_POLICY_RANGE_RANKED operations cause an address range to be tagged. The +field is generated by the policy tool, and is not the same as a tag specifier. +Tag types are not stable, and can and will change from build to build of policies. +These records are generated by the policy tool, exclusively. +The tag category and rank fields are used to determine overrides of tags. A tag in +the same category as another with a higher rank will supercede a lower ranked tag +on any given address. + */ + +/* + Meta data operations: + */ +#define DMD_SET_BASE_ADDRESS_OP 1u +#define DMD_TAG_ADDRESS_OP 2u +#define DMD_TAG_ADDRESS_RANGE_OP 3u +#define DMD_TAG_POLICY_SYMBOL 4u /* deprecated? */ +#define DMD_TAG_POLICY_RANGE 5u /* deprecated? */ +#define DMD_TAG_POLICY_SYMBOL_RANKED 6u +#define DMD_TAG_POLICY_RANGE_RANKED 7u +#define DMD_END_BLOCK 8u +#define DMD_END_BLOCK_WEAK_DECL_HACK 9u +#define DMD_FUNCTION_RANGE 10u /*Followed by 32bit start and 32bit end addresses*/ + +/* + Tag specifiers... also serve as offset in MCSymbol ISPMetadata flags struct. + */ +#define DMT_CFI3L_VALID_TGT 1u +#define DMT_STACK_PROLOGUE_AUTHORITY 2u +#define DMT_STACK_EPILOGUE_AUTHORITY 3u +#define DMT_FPTR_STORE_AUTHORITY 4u +#define DMT_BRANCH_VALID_TGT 5u +#define DMT_RET_VALID_TGT 6u +#define DMT_RETURN_INSTR 7u +#define DMT_CALL_INSTR 8u +#define DMT_BRANCH_INSTR 9u +#define DMT_FPTR_CREATE_AUTHORITY 10u +#define DMT_WRITE_ONCE 11u + +//#define WriteOnceFlagVal ((0x1) << (MachineInstr::MaxFlagShift + 1)) + +#include +#include "llvm/CodeGen/MachineInstr.h" + +using namespace std; +using namespace llvm; + +const std::map MachineInstFlagToMetadata = { + {MachineInstr::FnProlog, DMT_STACK_PROLOGUE_AUTHORITY}, + {MachineInstr::FnEpilog, DMT_STACK_EPILOGUE_AUTHORITY}, + {MachineInstr::FPtrStore, DMT_FPTR_STORE_AUTHORITY}, + {MachineInstr::FPtrCreate, DMT_FPTR_CREATE_AUTHORITY}, + {MachineInstr::IsReturn, DMT_RETURN_INSTR}, + {MachineInstr::IsCall, DMT_CALL_INSTR}, + {MachineInstr::IsBranch, DMT_BRANCH_INSTR}, + {MachineInstr::CallTarget, DMT_CFI3L_VALID_TGT}, + {MachineInstr::ReturnTarget, DMT_RET_VALID_TGT}, + {MachineInstr::BranchTarget, DMT_BRANCH_VALID_TGT} +}; + +#endif diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index d95baf9fae5a..7528304ceb31 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -3022,20 +3022,23 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock &MBB) { emitBasicBlockLoopComments(MBB, MLI, *this); } + // TODO: condition this on SSITH compilation // Print the main label for the block. - if (MBB.pred_empty() || - (isBlockOnlyReachableByFallthrough(&MBB) && !MBB.isEHFuncletEntry() && - !MBB.hasLabelMustBeEmitted())) { - if (isVerbose()) { - // NOTE: Want this comment at start of line, don't emit with AddComment. - OutStreamer->emitRawComment(" %bb." + Twine(MBB.getNumber()) + ":", - false); - } - } else { - if (isVerbose() && MBB.hasLabelMustBeEmitted()) - OutStreamer->AddComment("Label of block must be emitted"); - OutStreamer->EmitLabel(MBB.getSymbol()); - } + // if (MBB.pred_empty() || + // (isBlockOnlyReachableByFallthrough(&MBB) && !MBB.isEHFuncletEntry() && + // !MBB.hasLabelMustBeEmitted())) { + // if (isVerbose()) { + // // NOTE: Want this comment at start of line, don't emit with AddComment. + // OutStreamer->emitRawComment(" %bb." + Twine(MBB.getNumber()) + ":", + // false); + // } + // } else { + // if (isVerbose() && MBB.hasLabelMustBeEmitted()) + // OutStreamer->AddComment("Label of block must be emitted"); + // OutStreamer->EmitLabel(MBB.getSymbol()); + // } + //SSITH - Always label basic block + OutStreamer->EmitLabel(MBB.getSymbol()); } void AsmPrinter::EmitBasicBlockEnd(const MachineBasicBlock &MBB) {} diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp index 18a99ce24032..48549c03d0b4 100644 --- a/llvm/lib/MC/MCObjectFileInfo.cpp +++ b/llvm/lib/MC/MCObjectFileInfo.cpp @@ -19,6 +19,7 @@ #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCSectionWasm.h" #include "llvm/MC/MCSectionXCOFF.h" +#include "llvm/MC/SSITHMetadata.h" using namespace llvm; @@ -489,6 +490,12 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) { Ctx->getELFSection(".eh_frame", EHSectionType, EHSectionFlags); StackSizesSection = Ctx->getELFSection(".stack_sizes", ELF::SHT_PROGBITS, 0); + + RemarksSection = + Ctx->getELFSection(".remarks", ELF::SHT_PROGBITS, ELF::SHF_EXCLUDE); + + ISPMetadataSection = + Ctx->getELFSection(ISP_METADATA_ELF_SECTION_NAME, ELF::SHT_PROGBITS, 0); } void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) { @@ -837,6 +844,8 @@ void MCObjectFileInfo::InitMCObjectFileInfo(const Triple &TheTriple, bool PIC, DwarfAccelNamespaceSection = nullptr; // Used only by selected targets. DwarfAccelTypesSection = nullptr; // Used only by selected targets. + ISPMetadataSection = nullptr; + TT = TheTriple; switch (TT.getObjectFormat()) { diff --git a/llvm/lib/Target/RISCV/CMakeLists.txt b/llvm/lib/Target/RISCV/CMakeLists.txt index 31a82be19812..b42bd8d52818 100644 --- a/llvm/lib/Target/RISCV/CMakeLists.txt +++ b/llvm/lib/Target/RISCV/CMakeLists.txt @@ -17,6 +17,8 @@ tablegen(LLVM RISCVGenSystemOperands.inc -gen-searchable-tables) add_public_tablegen_target(RISCVCommonTableGen) add_llvm_target(RISCVCodeGen + ISPAsmPrinter.cpp + ISPMetadataPass.cpp RISCVAsmPrinter.cpp RISCVCallLowering.cpp RISCVExpandPseudoInsts.cpp diff --git a/llvm/lib/Target/RISCV/ISP.h b/llvm/lib/Target/RISCV/ISP.h new file mode 100644 index 000000000000..2c168e64821f --- /dev/null +++ b/llvm/lib/Target/RISCV/ISP.h @@ -0,0 +1,54 @@ +//===-- RISCV.h - Top-level interface for RISCV -----------------*- 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 +// +//===----------------------------------------------------------------------===// +// +// This file contains the entry points for global functions defined in the LLVM +// RISC-V back-end. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_RISCV_ISP_H +#define LLVM_LIB_TARGET_RISCV_ISP_H + +#include "llvm/MC/SSITHMetadata.h" +#include "MCTargetDesc/RISCVELFStreamer.h" + +using namespace llvm; + +class ISPTargetELFStreamer : public RISCVTargetELFStreamer { +public: + ISPTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI); + + virtual void emitLabel(MCSymbol *Symbol) override; + virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &) override; + virtual void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment) override; + + void EmitSSITHMetadataEntry(SmallVector &Fixups, + uint8_t MD_type, uint8_t tag); + +private: + + bool ISPSecInitialized = false; + + void EmitMCSymbolMetadata(MCSymbol *Sym); + void EmitMCInstMetadata(const MCInst &Inst); + + void EmitSSITHMetadataFnRange(MCSymbol *begin, MCSymbol *end); + void EmitSSITHMetadataHeader(MCObjectStreamer &Streamer); +}; + +namespace llvm { +class PassRegistry; +class FunctionPass; + +FunctionPass *createRISCVISPMetadataPass(); +void initializeRISCVISPMetadataPass(PassRegistry &); + +} + +#endif diff --git a/llvm/lib/Target/RISCV/ISPAsmPrinter.cpp b/llvm/lib/Target/RISCV/ISPAsmPrinter.cpp new file mode 100644 index 000000000000..b7980b23cde2 --- /dev/null +++ b/llvm/lib/Target/RISCV/ISPAsmPrinter.cpp @@ -0,0 +1,99 @@ +//===-- ISPAsmPrinter.cpp - ISP LLVM assembly writer ----------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This file contains a printer that hooks the RISCV Printer in order to +// implement metadata output features. +// +//===----------------------------------------------------------------------===// + +#include "llvm/CodeGen/MachineInstr.h" +#include "RISCV.h" +#include "RISCVAsmPrinter.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCStreamer.h" +#include "llvm/Support/TargetRegistry.h" + +#include "ISP.h" + +using namespace llvm; + +class ISPAsmPrinter : public RISCVAsmPrinter { + +public: + explicit ISPAsmPrinter(TargetMachine &TM, + std::unique_ptr Streamer) + : RISCVAsmPrinter(TM, std::move(Streamer)) {} + + void EmitFnRangeMetadata(MCSymbol *begin, MCSymbol *end); + + void EmitInstruction(const MachineInstr *MI) override; +}; + + +//SSITH +void ISPAsmPrinter::EmitFnRangeMetadata(MCSymbol *begin, MCSymbol *end){ + + SmallVector Fixups; + + MCContext &Ctx = OutContext; + const MCExpr *MEbegin = MCSymbolRefExpr::create(begin, MCSymbolRefExpr::VK_None, Ctx); + const MCExpr *MEend = MCSymbolRefExpr::create(end, MCSymbolRefExpr::VK_None, Ctx); + + //Push fixups -- the linker will write the 4 byte address for us + Fixups.push_back( + MCFixup::create(0, MEbegin, MCFixupKind(FK_Data_4), SMLoc::getFromPointer(nullptr))); + Fixups.push_back( + MCFixup::create(0, MEend, MCFixupKind(FK_Data_4), SMLoc::getFromPointer(nullptr))); + + // TODO: Pointer disasters + OutStreamer->EmitLabel(end); + ((ISPTargetELFStreamer*)(OutStreamer->getTargetStreamer()))->EmitSSITHMetadataEntry(Fixups, DMD_FUNCTION_RANGE, 0); +} + +static void LowerToSSITHEpilogStore(const MachineInstr *MI, MCInst &OutMI, + const AsmPrinter &AP) { + OutMI.setOpcode(RISCV::SW); + + bool first = true; + for (const MachineOperand &MO : MI->operands()) { + MCOperand MCOp; + if(first){ + OutMI.addOperand(MCOperand::createReg(RISCV::X0)); + first = false; + } + else if (LowerRISCVMachineOperandToMCOperand(MO, MCOp, AP)) + OutMI.addOperand(MCOp); + } + + OutMI.setFlags(MI->getFlags()); +} + +void ISPAsmPrinter::EmitInstruction(const MachineInstr *MI) { + + RISCVAsmPrinter::EmitInstruction(MI); + + // fn range avoids NoCFI on C code stuff + // TODO: this may or may not be in the "right" place... + if(MI->isReturn()) + EmitFnRangeMetadata(CurrentFnSym, OutContext.createTempSymbol()); + + //SSITH - clean up in function epilog + if(MI->getFlag(MachineInstr::FnEpilog) && MI->getOpcode() == RISCV::LW){ + //Emit our new store + MCInst SSITHStore; + LowerToSSITHEpilogStore(MI, SSITHStore, *this); + EmitToStreamer(*OutStreamer, SSITHStore); + } + +} + +// Force static initialization. +extern "C" void LLVMInitializeRISCVAsmPrinter() { + RegisterAsmPrinter X(getTheRISCV32Target()); + RegisterAsmPrinter Y(getTheRISCV64Target()); +} diff --git a/llvm/lib/Target/RISCV/ISPAsmPrinter.h b/llvm/lib/Target/RISCV/ISPAsmPrinter.h new file mode 100644 index 000000000000..cda81d8b2fdc --- /dev/null +++ b/llvm/lib/Target/RISCV/ISPAsmPrinter.h @@ -0,0 +1,19 @@ +#include "llvm/CodeGen/MachineInstr.h" +#include "RISCV.h" +#include "RISCVAsmPrinter.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCStreamer.h" + +using namespace llvm; + +class ISPAsmPrinter : public RISCVAsmPrinter { + +public: + explicit ISPAsmPrinter(TargetMachine &TM, + std::unique_ptr Streamer) + : RISCVAsmPrinter(TM, std::move(Streamer)) {} + + void EmitFnRangeMetadata(MCSymbol *begin, MCSymbol *end); + + void EmitInstruction(const MachineInstr *MI) override; +}; diff --git a/llvm/lib/Target/RISCV/ISPMetadataPass.cpp b/llvm/lib/Target/RISCV/ISPMetadataPass.cpp new file mode 100644 index 000000000000..da7f46392d0c --- /dev/null +++ b/llvm/lib/Target/RISCV/ISPMetadataPass.cpp @@ -0,0 +1,121 @@ +//===-- ISPMetadataPass.cpp - Calculate metadata for ISP ------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This file contains a pass that identifies and adds metadata to certain +// instructions +// +//===----------------------------------------------------------------------===// + +#include "RISCV.h" +#include "ISP.h" + +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineInstr.h" + +using namespace llvm; + +#define RISCV_ISP_METADATA_NAME "RISCV ISP Metadata calculation pass" + +namespace { + +class RISCVISPMetadata : public MachineFunctionPass { +public: + static char ID; + + RISCVISPMetadata() : MachineFunctionPass(ID) { + initializeRISCVISPMetadataPass(*PassRegistry::getPassRegistry()); + } + + bool runOnMachineFunction(MachineFunction &MF) override; + + StringRef getPassName() const override { return RISCV_ISP_METADATA_NAME; } +}; + +char RISCVISPMetadata::ID = 1; + +static void setMIFlags(MachineInstr *MI) { + + if ( MI->isReturn() && !MI->isCall() ) { + MI->setFlag(MachineInstr::IsReturn); + MI->setFlag(MachineInstr::FnEpilog); + } + else if ( MI->isCall() ) + MI->setFlags(MachineInstr::IsCall); + else if ( MI->isBranch() ) + MI->setFlags(MachineInstr::IsBranch); + +} + +bool RISCVISPMetadata::runOnMachineFunction(MachineFunction &MF) { + + for (auto &MBB : MF) { + + // check first instruction + auto MI = MBB.getFirstNonDebugInstr(); + setMIFlags(&*MI); + if ( MI == MBB.end() ) + continue; + + MBB.getSymbol()->modifyFlags((&MBB == &*MF.begin() ? + MachineInstr::CallTarget : + MachineInstr::BranchTarget), + 0); + + for(auto &pred : MBB.predecessors()){ + const auto &last = pred->getLastNonDebugInstr(); + if(last != pred->end()) { + if(last->isCall()) { + MI->setFlag(MachineInstr::ReturnTarget); + } + if(last->isBranch()) + MI->setFlag(MachineInstr::BranchTarget); + } + } + + // check all other instructions + + auto last = MI; + for( auto MI = std::next(MBB.instr_begin()); MI != MBB.instr_end(); MI++ ) { + + setMIFlags(&*MI); + + //The zero size instructions from RISCVInstrInfo.cpp - getInstSizeInBytes + //wasn't obvious how to call it, so here's this unmaintable approach + switch(MI->getOpcode()){ + case TargetOpcode::EH_LABEL: + case TargetOpcode::IMPLICIT_DEF: + case TargetOpcode::KILL: + case TargetOpcode::DBG_VALUE: + continue; + default: //do nothing + break; //breaks the switch not the loop + } + + if(last->isCall()) + MI->setFlag(MachineInstr::ReturnTarget); + + if(last->isBranch()) + MI->setFlag(MachineInstr::BranchTarget); + + last = MI; + } + } + + return false; +} + +} // end of anonymous namespace + +INITIALIZE_PASS(RISCVISPMetadata, "riscv-isp-metadata", + RISCV_ISP_METADATA_NAME, false, false) +namespace llvm { + +FunctionPass *createRISCVISPMetadataPass() { return new RISCVISPMetadata(); } + +} // end of namespace llvm diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/CMakeLists.txt b/llvm/lib/Target/RISCV/MCTargetDesc/CMakeLists.txt index df2d15dc7983..1657d7773758 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/CMakeLists.txt +++ b/llvm/lib/Target/RISCV/MCTargetDesc/CMakeLists.txt @@ -1,5 +1,6 @@ add_llvm_component_library(LLVMRISCVDesc RISCVAsmBackend.cpp + ISPELFStreamer.cpp RISCVELFObjectWriter.cpp RISCVInstPrinter.cpp RISCVMCAsmInfo.cpp diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/ISPELFStreamer.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/ISPELFStreamer.cpp new file mode 100644 index 000000000000..dddd5dbde8cf --- /dev/null +++ b/llvm/lib/Target/RISCV/MCTargetDesc/ISPELFStreamer.cpp @@ -0,0 +1,166 @@ +//===-- ISPELFStreamer.cpp - ISP ELF Target Streamer Methods --------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This file provides ISP specific target streamer methods. +// +//===----------------------------------------------------------------------===// + +#include "MCTargetDesc/RISCVELFStreamer.h" +#include "MCTargetDesc/RISCVMCExpr.h" +#include "MCTargetDesc/RISCVAsmBackend.h" +#include "MCTargetDesc/RISCVMCTargetDesc.h" +#include "Utils/RISCVBaseInfo.h" +#include "llvm/BinaryFormat/ELF.h" +#include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCObjectWriter.h" +#include "llvm/MC/MCObjectFileInfo.h" +#include "llvm/CodeGen/MachineInstr.h" + +#include "ISP.h" + +ISPTargetELFStreamer::ISPTargetELFStreamer(MCStreamer &S, + const MCSubtargetInfo &STI) + : RISCVTargetELFStreamer(S, STI) { + + ISPSecInitialized = false; +} + +//SSITH Addition +void ISPTargetELFStreamer::EmitSSITHMetadataHeader(MCObjectStreamer &Streamer){ + + SmallString<256> Code; + raw_svector_ostream VecOS(Code); + + printf("emitting metadata header!\n"); + + //Emit the Metadata tag + uint8_t MD = DMD_SET_BASE_ADDRESS_OP; + support::endian::write(VecOS, MD, support::little); + + uint64_t Base = 0u; + support::endian::write(VecOS, Base, support::little); + + MCDataFragment *DF = Streamer.getOrCreateDataFragment(); + DF->getContents().append(Code.begin(), Code.end()); + + ISPSecInitialized = true; +} + +//SSITH Addition +void ISPTargetELFStreamer::EmitSSITHMetadataEntry(SmallVector &Fixups, + uint8_t MD_type, uint8_t tag){ + SmallString<256> Code; + raw_svector_ostream VecOS(Code); + MCDataFragment *DF; + + bool switchSection = false; + + MCELFStreamer &Streamer = getStreamer(); + MCContext &Context = Streamer.getContext(); + + const auto ISPMetadataSection = + Context.getObjectFileInfo()->getISPMetadataSection(); + + if ( Streamer.getCurrentSectionOnly() != ISPMetadataSection ) { + switchSection = true; + Streamer.PushSection(); + Streamer.SwitchSection(ISPMetadataSection); + } + + if ( !ISPSecInitialized ) + EmitSSITHMetadataHeader(Streamer); + + // Emit the Metadata tag + assert(MD_type && "[SSITH Error] MD_TYPE must be nonnull"); + uint8_t MD = MD_type; + support::endian::write(VecOS, MD, support::little); + + //Our placeholder 0 bytes for the relative address + uint32_t Bits = 0; + support::endian::write(VecOS, Bits, support::little); + + if(MD_type == DMD_FUNCTION_RANGE) + support::endian::write(VecOS, Bits, support::little); + + //The metadata tag specifier + if(MD_type != DMD_FUNCTION_RANGE){ + assert(tag && + "[SSITH Error] Must have a non null tag for op types other than function range"); + MD = tag; + support::endian::write(VecOS, MD, support::little); + } + + DF = Streamer.getOrCreateDataFragment(); + // Add the fixup and data. + for(unsigned i = 0; i < Fixups.size(); i++){ + //hack this to account for the prologue byte + Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size() + 1 + i*4); + DF->getFixups().push_back(Fixups[i]); + } + DF->getContents().append(Code.begin(), Code.end()); + + if ( switchSection ) + Streamer.PopSection(); +} + +void ISPTargetELFStreamer::EmitMCSymbolMetadata(MCSymbol *Sym) { + + const MCExpr *ME = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getStreamer().getContext()); + + SmallVector Fixups; + Fixups.push_back( + MCFixup::create(0, ME, MCFixupKind(FK_Data_4), SMLoc::getFromPointer(nullptr))); + + for ( auto const &pair : MachineInstFlagToMetadata ) + if ( Sym->getFlag(pair.first) ) + EmitSSITHMetadataEntry(Fixups, DMD_TAG_ADDRESS_OP, pair.second); +} + +void ISPTargetELFStreamer::EmitMCInstMetadata(const MCInst &Inst) { + + // note: need one temp label per metadata entry, + // even if they're on the same instruction + for ( auto const &pair : MachineInstFlagToMetadata ) { + if ( Inst.getFlag(pair.first) ) { + MCSymbol *InstSym = getStreamer().getContext().createTempSymbol(); + InstSym->setFlag(pair.first); + getStreamer().EmitLabel(InstSym); + } + } + +} + +void ISPTargetELFStreamer::emitLabel(MCSymbol *Symbol) { + + RISCVTargetELFStreamer::emitLabel(Symbol); + + EmitMCSymbolMetadata(Symbol); + + return; +} + +void ISPTargetELFStreamer::emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) { + + RISCVTargetELFStreamer::emitInstruction(Inst, STI); + + EmitMCInstMetadata(Inst); + + return; +} + +void ISPTargetELFStreamer::emitCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment) { + + RISCVTargetELFStreamer::emitCommonSymbol(Symbol, Size, ByteAlignment); + + EmitMCSymbolMetadata(Symbol); + + return; +} + diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp index d231280cc1a4..46d873d3ca5b 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp @@ -27,6 +27,8 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/TargetRegistry.h" +#include "ISP.h" + #define GET_INSTRINFO_MC_DESC #include "RISCVGenInstrInfo.inc" @@ -82,7 +84,7 @@ static MCTargetStreamer * createRISCVObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) { const Triple &TT = STI.getTargetTriple(); if (TT.isOSBinFormatELF()) - return new RISCVTargetELFStreamer(S, STI); + return new ISPTargetELFStreamer(S, STI); return nullptr; } diff --git a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp index 871be10e8c1a..19c97251607d 100644 --- a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp +++ b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp @@ -125,7 +125,7 @@ bool RISCVAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, } // Force static initialization. -extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVAsmPrinter() { - RegisterAsmPrinter X(getTheRISCV32Target()); - RegisterAsmPrinter Y(getTheRISCV64Target()); -} +//extern "C" void LLVMInitializeRISCVAsmPrinter() { +// RegisterAsmPrinter X(getTheRISCV32Target()); +// RegisterAsmPrinter Y(getTheRISCV64Target()); +//} diff --git a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp index de71c01753de..9f36d6e7ccbe 100644 --- a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp +++ b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp @@ -30,6 +30,9 @@ #include "llvm/Support/FormattedStream.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Target/TargetOptions.h" + +#include "ISP.h" + using namespace llvm; extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTarget() { @@ -38,6 +41,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTarget() { auto PR = PassRegistry::getPassRegistry(); initializeGlobalISel(*PR); initializeRISCVExpandPseudoPass(*PR); + initializeRISCVISPMetadataPass(*PR); } static StringRef computeDataLayout(const Triple &TT) { @@ -174,6 +178,7 @@ void RISCVPassConfig::addPreEmitPass2() { // possibility for other passes to break the requirements for forward // progress in the LR/SC block. addPass(createRISCVExpandPseudoPass()); + addPass(createRISCVISPMetadataPass()); } void RISCVPassConfig::addPreRegAlloc() { From ef074a745ef9adb92782a708c3926e504d8679ab Mon Sep 17 00:00:00 2001 From: Scott Brookes Date: Wed, 19 Jun 2019 15:30:58 -0400 Subject: [PATCH 03/14] clean a mistake --- llvm/include/llvm/MC/MCStreamer.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h index c8aeebd775f1..cbcc3180eb2e 100644 --- a/llvm/include/llvm/MC/MCStreamer.h +++ b/llvm/include/llvm/MC/MCStreamer.h @@ -13,6 +13,7 @@ #ifndef LLVM_MC_MCSTREAMER_H #define LLVM_MC_MCSTREAMER_H +#include "llvm/MC/SSITHMetadata.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/Optional.h" @@ -597,7 +598,7 @@ class MCStreamer { /// \param ByteAlignment - The alignment of the symbol if /// non-zero. This must be a power of 2. virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, - unsigned ByteAlignment); + unsigned ByteAlignment) = 0; /// Emit a local common (.lcomm) symbol. /// @@ -618,6 +619,10 @@ class MCStreamer { uint64_t Size = 0, unsigned ByteAlignment = 0, SMLoc Loc = SMLoc()) = 0; + /// SSITH metadata write - only defined by MCELFStreamer + virtual void EmitSSITHMetadataEntry(SmallVector &Fixups, + uint8_t MD_type, uint8_t tag) {} + /// Emit a thread local bss (.tbss) symbol. /// /// \param Section - The thread local common section. From f92873b6a1b0282e843aa4694811fbe2b0ca8a78 Mon Sep 17 00:00:00 2001 From: Amanda Strnad Date: Thu, 3 Oct 2019 08:41:17 -0400 Subject: [PATCH 04/14] Build stuff --- Makefile.isp | 60 ++++++++++++++++++++++++++++++++ isp-support/README | 26 ++++++++++++++ isp-support/check_ninja_version | 12 +++++++ isp-support/install-dependencies | 29 +++++++++++++++ 4 files changed, 127 insertions(+) create mode 100644 Makefile.isp create mode 100644 isp-support/README create mode 100755 isp-support/check_ninja_version create mode 100755 isp-support/install-dependencies diff --git a/Makefile.isp b/Makefile.isp new file mode 100644 index 000000000000..ea78f46b197f --- /dev/null +++ b/Makefile.isp @@ -0,0 +1,60 @@ +.PHONY: all +.PHONY: debug +.PHONY: release +.PHONY: install +.PHONY: clean + +export ISP_PREFIX ?= $(HOME)/.local/isp/ + +ifeq "$(shell isp-support/check_ninja_version)" "System ninja is new enough" + NINJA := ninja +else + NINJA := $(HOME)/.local/bin/ninja +endif + +BUILD_TYPE ?= debug + +COMMON_CMAKE_FLAGS += -G "Ninja" +COMMON_CMAKE_FLAGS += -DLLVM_ENABLE_PROJECTS="clang" +COMMON_CMAKE_FLAGS += -DCMAKE_MAKE_PROGRAM=$(NINJA) +COMMON_CMAKE_FLAGS += -DCMAKE_INSTALL_PREFIX=$(ISP_PREFIX) +COMMON_CMAKE_FLAGS += -DCMAKE_C_COMPILER=clang +COMMON_CMAKE_FLAGS += -DCMAKE_CXX_COMPILER=clang++ +COMMON_CMAKE_FLAGS += -DLLVM_BINUTILS_INCDIR=/usr/include +COMMON_CMAKE_FLAGS += -DBUILD_SHARED_LIBS=True +COMMON_CMAKE_FLAGS += -DLLVM_OPTIMIZED_TABLEGEN=True +COMMON_CMAKE_FLAGS += -DLLVM_BUILD_TESTS=True +COMMON_CMAKE_FLAGS += -DDEFAULT_SYSROOT=$(ISP_PREFIX)/riscv32-unknown-elf +COMMON_CMAKE_FLAGS += -DLLVM_DEFAULT_TARGET_TRIPLE="riscv32-unknown-elf" +COMMON_CMAKE_FLAGS += -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD="RISCV" +COMMON_CMAKE_FLAGS += -DLLVM_TARGETS_TO_BUILD="" + +DEBUG_CMAKE_FLAGS := -DCMAKE_BUILD_TYPE=Debug +DEBUG_CMAKE_FLAGS += -DLLVM_ENABLE_ASSERTIONS=ON +DEBUG_CMAKE_FLAGS += -DCMAKE_C_FLAGS=-fstandalone-debug +DEBUG_CMAKE_FLAGS += -DCMAKE_CXX_FLAGS=-fstandalone-debug + +RELEASE_CMAKE_FLAGS := -DCMAKE_BUILD_TYPE=Release + +debug-build/build.ninja: CMAKE_FLAGS := $(COMMON_CMAKE_FLAGS) $(DEBUG_CMAKE_FLAGS) + +release-build/build.ninja: CMAKE_FLAGS := $(COMMON_CMAKE_FLAGS) $(RELEASE_CMAKE_FLAGS) + +all: $(BUILD_TYPE) + +$(BUILD_TYPE): $(BUILD_TYPE)-build/build.ninja + $(NINJA) -C $(BUILD_TYPE)-build + +$(BUILD_TYPE)-build/build.ninja: + $(RM) -r $(BUILD_TYPE)-build + mkdir -p $(BUILD_TYPE)-build + cd $(BUILD_TYPE)-build; cmake $(CMAKE_FLAGS) ../llvm + +install: $(BUILD_TYPE)-install + +debug-install release-install: %-install: $* + $(NINJA) -C $*-build install + +clean: + $(RM) -r debug-build + $(RM) -r release-build diff --git a/isp-support/README b/isp-support/README new file mode 100644 index 000000000000..86d110d17f48 --- /dev/null +++ b/isp-support/README @@ -0,0 +1,26 @@ +Best results obtained by using the gold linker. Your ld is likely a symlink, +point it at ld.gold + +Be sure to clone recursively + +To build the llvm riscv cross compiler first make sure that you have a riscv +toolchain installed. I worked with the instructions here for a clean riscv +toolchain: + +https://github.com/lowRISC/riscv-llvm + +Then run the configure script. I *strongly* recommend you let it install the +same version of cmake and ninja that I was using (the latest release as of May +22, 2018). It will also ask you for the base path to the riscv toolchain. This +will enable the cross compiler to actually work, and is where the cross compiler +will get installed. + +./configure.sh + +After that, you can build either the debug or release version. I have been +working with the debug version during development, and strongly recommend it. +The release version is currently *untested* and *unsupported*. + +cd debug-build +ninja +ninja install diff --git a/isp-support/check_ninja_version b/isp-support/check_ninja_version new file mode 100755 index 000000000000..a6370c10fd8b --- /dev/null +++ b/isp-support/check_ninja_version @@ -0,0 +1,12 @@ +#!/bin/bash + +version=`ninja --version`; +check="1.8.2"; +winner=`echo -e "${version}\n${check}" | sort -nr | head -1`; +if [[ "${winner}" = "${version}" ]]; then + echo "System ninja is new enough" + exit 0 +else + echo "System ninja is too old" + exit 1 +fi diff --git a/isp-support/install-dependencies b/isp-support/install-dependencies new file mode 100755 index 000000000000..31aa4162c4f9 --- /dev/null +++ b/isp-support/install-dependencies @@ -0,0 +1,29 @@ +#!/bin/bash + +set -e + +apt-get update + +apt-get install -y \ + binutils-dev \ + build-essential \ + clang \ + cmake \ + unzip \ + wget \ + zlib1g-dev + +ninja_check() { + md5sum --quiet -c <<< "540b5a37ac9d822b07179ec1771855ae $HOME/.local/bin/ninja" +} + +if [ -f $HOME/.local/bin/ninja ]; then + ninja_check +else + wget https://github.com/ninja-build/ninja/releases/download/v1.8.2/ninja-linux.zip + unzip -o ninja-linux.zip + mkdir -p $HOME/.local/bin + mv ninja $HOME/.local/bin + rm ninja-linux.zip + ninja_check +fi From 6a076095ec67185751f76a35892f288659e6e727 Mon Sep 17 00:00:00 2001 From: Amanda Strnad Date: Thu, 3 Oct 2019 10:52:41 -0400 Subject: [PATCH 05/14] Add some dependencies --- llvm/include/llvm/IR/CMakeLists.txt | 1 + llvm/include/llvm/module.modulemap | 1 + llvm/lib/IR/CMakeLists.txt | 1 + llvm/lib/MC/CMakeLists.txt | 3 +++ 4 files changed, 6 insertions(+) diff --git a/llvm/include/llvm/IR/CMakeLists.txt b/llvm/include/llvm/IR/CMakeLists.txt index c8edc29bd887..3a65a357ee02 100644 --- a/llvm/include/llvm/IR/CMakeLists.txt +++ b/llvm/include/llvm/IR/CMakeLists.txt @@ -1,5 +1,6 @@ set(LLVM_TARGET_DEFINITIONS Attributes.td) tablegen(LLVM Attributes.inc -gen-attrs) +add_public_tablegen_target(attributes_gen) set(LLVM_TARGET_DEFINITIONS Intrinsics.td) tablegen(LLVM IntrinsicImpl.inc -gen-intrinsic-impl) diff --git a/llvm/include/llvm/module.modulemap b/llvm/include/llvm/module.modulemap index 1e6c570beddb..bcbed3a5aae1 100644 --- a/llvm/include/llvm/module.modulemap +++ b/llvm/include/llvm/module.modulemap @@ -219,6 +219,7 @@ module LLVM_Pass { module LLVM_intrinsic_gen { requires cplusplus + requires attribute_gen // Delay building the modules containing dependencies to Attributes.h and // Intrinsics.h because they need to be generated by tablegen first. diff --git a/llvm/lib/IR/CMakeLists.txt b/llvm/lib/IR/CMakeLists.txt index 8fcc10fa38af..72d570b0c58e 100644 --- a/llvm/lib/IR/CMakeLists.txt +++ b/llvm/lib/IR/CMakeLists.txt @@ -62,4 +62,5 @@ add_llvm_component_library(LLVMCore DEPENDS intrinsics_gen + attributes_gen ) diff --git a/llvm/lib/MC/CMakeLists.txt b/llvm/lib/MC/CMakeLists.txt index de2e47d8d9b2..6db1eddae4aa 100644 --- a/llvm/lib/MC/CMakeLists.txt +++ b/llvm/lib/MC/CMakeLists.txt @@ -61,6 +61,9 @@ add_llvm_component_library(LLVMMC ADDITIONAL_HEADER_DIRS ${LLVM_MAIN_INCLUDE_DIR}/llvm/MC + + DEPENDS + attributes_gen ) add_subdirectory(MCParser) From a4db079c4b67b9d4be96f3f84e6951d3a5144bc7 Mon Sep 17 00:00:00 2001 From: Amanda Strnad Date: Fri, 4 Oct 2019 10:27:41 -0400 Subject: [PATCH 06/14] Reorder to avoid a bad dereference --- llvm/lib/Target/RISCV/ISPMetadataPass.cpp | 103 +++++++++++----------- 1 file changed, 52 insertions(+), 51 deletions(-) diff --git a/llvm/lib/Target/RISCV/ISPMetadataPass.cpp b/llvm/lib/Target/RISCV/ISPMetadataPass.cpp index da7f46392d0c..c537fc90a24d 100644 --- a/llvm/lib/Target/RISCV/ISPMetadataPass.cpp +++ b/llvm/lib/Target/RISCV/ISPMetadataPass.cpp @@ -54,59 +54,60 @@ static void setMIFlags(MachineInstr *MI) { bool RISCVISPMetadata::runOnMachineFunction(MachineFunction &MF) { - for (auto &MBB : MF) { - - // check first instruction - auto MI = MBB.getFirstNonDebugInstr(); - setMIFlags(&*MI); - if ( MI == MBB.end() ) - continue; - - MBB.getSymbol()->modifyFlags((&MBB == &*MF.begin() ? - MachineInstr::CallTarget : - MachineInstr::BranchTarget), - 0); - - for(auto &pred : MBB.predecessors()){ - const auto &last = pred->getLastNonDebugInstr(); - if(last != pred->end()) { - if(last->isCall()) { - MI->setFlag(MachineInstr::ReturnTarget); - } - if(last->isBranch()) - MI->setFlag(MachineInstr::BranchTarget); - } + for (auto &MBB : MF) { + + // check first instruction + auto MI = MBB.getFirstNonDebugInstr(); + if ( MI == MBB.end() ) + continue; + + MBB.getSymbol()->modifyFlags((&MBB == &*MF.begin() ? + MachineInstr::CallTarget : + MachineInstr::BranchTarget), + 0); + + setMIFlags(&*MI); + + for(auto &pred : MBB.predecessors()){ + const auto &last = pred->getLastNonDebugInstr(); + if(last != pred->end()) { + if(last->isCall()) { + MI->setFlag(MachineInstr::ReturnTarget); + } + if(last->isBranch()) + MI->setFlag(MachineInstr::BranchTarget); + } + } + + // check all other instructions + + auto last = MI; + for( auto MI = std::next(MBB.instr_begin()); MI != MBB.instr_end(); MI++ ) { + + setMIFlags(&*MI); + + //The zero size instructions from RISCVInstrInfo.cpp - getInstSizeInBytes + //wasn't obvious how to call it, so here's this unmaintable approach + switch(MI->getOpcode()){ + case TargetOpcode::EH_LABEL: + case TargetOpcode::IMPLICIT_DEF: + case TargetOpcode::KILL: + case TargetOpcode::DBG_VALUE: + continue; + default: //do nothing + break; //breaks the switch not the loop + } + + if(last->isCall()) + MI->setFlag(MachineInstr::ReturnTarget); + + if(last->isBranch()) + MI->setFlag(MachineInstr::BranchTarget); + + last = MI; + } } - // check all other instructions - - auto last = MI; - for( auto MI = std::next(MBB.instr_begin()); MI != MBB.instr_end(); MI++ ) { - - setMIFlags(&*MI); - - //The zero size instructions from RISCVInstrInfo.cpp - getInstSizeInBytes - //wasn't obvious how to call it, so here's this unmaintable approach - switch(MI->getOpcode()){ - case TargetOpcode::EH_LABEL: - case TargetOpcode::IMPLICIT_DEF: - case TargetOpcode::KILL: - case TargetOpcode::DBG_VALUE: - continue; - default: //do nothing - break; //breaks the switch not the loop - } - - if(last->isCall()) - MI->setFlag(MachineInstr::ReturnTarget); - - if(last->isBranch()) - MI->setFlag(MachineInstr::BranchTarget); - - last = MI; - } - } - return false; } From 4d8e9c63ef9aa1d7f56ef3040b260ad94d9d0957 Mon Sep 17 00:00:00 2001 From: Amanda Strnad Date: Fri, 4 Oct 2019 16:01:41 -0400 Subject: [PATCH 07/14] Change to a misleadingly similar function `setFlags` clears some flags, while `setFlag` only changes the specified flag. This resolves an issue where instructions weren't checked as target for both calls and branches. --- llvm/lib/Target/RISCV/ISPMetadataPass.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/RISCV/ISPMetadataPass.cpp b/llvm/lib/Target/RISCV/ISPMetadataPass.cpp index c537fc90a24d..a80769a7c030 100644 --- a/llvm/lib/Target/RISCV/ISPMetadataPass.cpp +++ b/llvm/lib/Target/RISCV/ISPMetadataPass.cpp @@ -46,9 +46,9 @@ static void setMIFlags(MachineInstr *MI) { MI->setFlag(MachineInstr::FnEpilog); } else if ( MI->isCall() ) - MI->setFlags(MachineInstr::IsCall); + MI->setFlag(MachineInstr::IsCall); else if ( MI->isBranch() ) - MI->setFlags(MachineInstr::IsBranch); + MI->setFlag(MachineInstr::IsBranch); } From a26b8c13ab5ade276053dae8ab5c205b95390d5f Mon Sep 17 00:00:00 2001 From: Amanda Strnad Date: Thu, 17 Oct 2019 12:58:28 -0400 Subject: [PATCH 08/14] Revert "Change to a misleadingly similar function" This reverts commit 0842ce85c1003157cd649ceebe72e37887dbb4cd. --- llvm/lib/Target/RISCV/ISPMetadataPass.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/RISCV/ISPMetadataPass.cpp b/llvm/lib/Target/RISCV/ISPMetadataPass.cpp index a80769a7c030..c537fc90a24d 100644 --- a/llvm/lib/Target/RISCV/ISPMetadataPass.cpp +++ b/llvm/lib/Target/RISCV/ISPMetadataPass.cpp @@ -46,9 +46,9 @@ static void setMIFlags(MachineInstr *MI) { MI->setFlag(MachineInstr::FnEpilog); } else if ( MI->isCall() ) - MI->setFlag(MachineInstr::IsCall); + MI->setFlags(MachineInstr::IsCall); else if ( MI->isBranch() ) - MI->setFlag(MachineInstr::IsBranch); + MI->setFlags(MachineInstr::IsBranch); } From 2bbe33477e9d7e7e8e62882f7a115c9aff7098b4 Mon Sep 17 00:00:00 2001 From: Amanda Strnad Date: Thu, 17 Oct 2019 12:58:44 -0400 Subject: [PATCH 09/14] Flags was still a uint16 in a couple places --- llvm/include/llvm/CodeGen/MachineInstr.h | 6 +++--- llvm/lib/CodeGen/MachineInstr.cpp | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/llvm/include/llvm/CodeGen/MachineInstr.h b/llvm/include/llvm/CodeGen/MachineInstr.h index 562313b45679..fe4ab8053ccb 100644 --- a/llvm/include/llvm/CodeGen/MachineInstr.h +++ b/llvm/include/llvm/CodeGen/MachineInstr.h @@ -332,9 +332,9 @@ class MachineInstr Flags |= (MachineInstrFlags_t)Flag; } - void setFlags(unsigned flags) { + void setFlags(MachineInstrFlags_t flags) { // Filter out the automatically maintained flags. - unsigned Mask = BundledPred | BundledSucc; + MachineInstrFlags_t Mask = BundledPred | BundledSucc; Flags = (Flags & Mask) | (flags & ~Mask); } @@ -1648,7 +1648,7 @@ class MachineInstr /// not modify the MIFlags of this MachineInstr. MachineInstrFlags_t mergeFlagsWith(const MachineInstr& Other) const; - static uint16_t copyFlagsFromInstruction(const Instruction &I); + static MachineInstrFlags_t copyFlagsFromInstruction(const Instruction &I); /// Copy all flags to MachineInst MIFlags void copyIRFlags(const Instruction &I); diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp index 2621551181ed..48accb546c5f 100644 --- a/llvm/lib/CodeGen/MachineInstr.cpp +++ b/llvm/lib/CodeGen/MachineInstr.cpp @@ -523,8 +523,8 @@ MachineInstrFlags_t MachineInstr::mergeFlagsWith(const MachineInstr &Other) cons return getFlags() | Other.getFlags(); } -uint16_t MachineInstr::copyFlagsFromInstruction(const Instruction &I) { - uint16_t MIFlags = 0; +MachineInstrFlags_t MachineInstr::copyFlagsFromInstruction(const Instruction &I) { + MachineInstrFlags_t MIFlags = 0; // Copy the wrapping flags. if (const OverflowingBinaryOperator *OB = dyn_cast(&I)) { From 87614ce1f2f462fc0717b4e629e9f7c08e8dd779 Mon Sep 17 00:00:00 2001 From: Jesse Millwood Date: Tue, 3 Mar 2020 10:03:38 -0500 Subject: [PATCH 10/14] Gitignore: Ignore build directories --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitignore b/.gitignore index dfeba61ddba1..45786bf9d754 100644 --- a/.gitignore +++ b/.gitignore @@ -54,3 +54,8 @@ autoconf/autom4te.cache .vs # clangd index .clangd + +#==============================================================================# +# Build Directories +#==============================================================================# +*-build From 54407160962167da86025d39a04b18e1881d3282 Mon Sep 17 00:00:00 2001 From: Jesse Millwood Date: Wed, 11 Mar 2020 13:08:08 -0400 Subject: [PATCH 11/14] SSITH: Fixed compiler errors --- llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 2 +- llvm/lib/Target/RISCV/ISPAsmPrinter.cpp | 1 + llvm/lib/Target/RISCV/RISCVAsmPrinter.h | 4 ++++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index 25df6466e886..22f267a9000c 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -1599,7 +1599,7 @@ const MCExpr *TargetLoweringObjectFileCOFF::lowerRelativeReference( static std::string APIntToHexString(const APInt &AI) { unsigned Width = (AI.getBitWidth() / 8) * 2; std::string HexString = AI.toString(16, /*Signed=*/false); - transform(HexString.begin(), HexString.end(), HexString.begin(), tolower); + transform(HexString, HexString.begin(), ::tolower); unsigned Size = HexString.size(); assert(Width >= Size && "hex string is too large!"); HexString.insert(HexString.begin(), Width - Size, '0'); diff --git a/llvm/lib/Target/RISCV/ISPAsmPrinter.cpp b/llvm/lib/Target/RISCV/ISPAsmPrinter.cpp index b7980b23cde2..43cc9463c8f0 100644 --- a/llvm/lib/Target/RISCV/ISPAsmPrinter.cpp +++ b/llvm/lib/Target/RISCV/ISPAsmPrinter.cpp @@ -17,6 +17,7 @@ #include "llvm/MC/MCContext.h" #include "llvm/MC/MCStreamer.h" #include "llvm/Support/TargetRegistry.h" +#include "TargetInfo/RISCVTargetInfo.h" #include "ISP.h" diff --git a/llvm/lib/Target/RISCV/RISCVAsmPrinter.h b/llvm/lib/Target/RISCV/RISCVAsmPrinter.h index 24639644fe94..9ffb187363fb 100644 --- a/llvm/lib/Target/RISCV/RISCVAsmPrinter.h +++ b/llvm/lib/Target/RISCV/RISCVAsmPrinter.h @@ -17,11 +17,15 @@ #include "llvm/CodeGen/MachineInstr.h" #include "llvm/MC/MCInst.h" #include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/ADT/Statistic.h" #define DEBUG_TYPE "asm-printer" using namespace llvm; +STATISTIC(RISCVNumInstrsCompressed, + "Number of RISC-V Compressed instructions emitted"); + class RISCVAsmPrinter : public AsmPrinter { public: explicit RISCVAsmPrinter(TargetMachine &TM, From 34aa20cfd34dfef6acd174e3011b3e2ad01857e1 Mon Sep 17 00:00:00 2001 From: Jesse Millwood Date: Wed, 11 Mar 2020 13:08:47 -0400 Subject: [PATCH 12/14] SSITH: Updated Makefile --- Makefile.isp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Makefile.isp b/Makefile.isp index ea78f46b197f..795447c31b81 100644 --- a/Makefile.isp +++ b/Makefile.isp @@ -24,10 +24,9 @@ COMMON_CMAKE_FLAGS += -DLLVM_BINUTILS_INCDIR=/usr/include COMMON_CMAKE_FLAGS += -DBUILD_SHARED_LIBS=True COMMON_CMAKE_FLAGS += -DLLVM_OPTIMIZED_TABLEGEN=True COMMON_CMAKE_FLAGS += -DLLVM_BUILD_TESTS=True -COMMON_CMAKE_FLAGS += -DDEFAULT_SYSROOT=$(ISP_PREFIX)/riscv32-unknown-elf -COMMON_CMAKE_FLAGS += -DLLVM_DEFAULT_TARGET_TRIPLE="riscv32-unknown-elf" -COMMON_CMAKE_FLAGS += -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD="RISCV" -COMMON_CMAKE_FLAGS += -DLLVM_TARGETS_TO_BUILD="" +COMMON_CMAKE_FLAGS += -DDEFAULT_SYSROOT=$(ISP_PREFIX)/riscv64-unknown-elf +COMMON_CMAKE_FLAGS += -DLLVM_DEFAULT_TARGET_TRIPLE="riscv64-unknown-elf" +COMMON_CMAKE_FLAGS += -DLLVM_TARGETS_TO_BUILD="RISCV" DEBUG_CMAKE_FLAGS := -DCMAKE_BUILD_TYPE=Debug DEBUG_CMAKE_FLAGS += -DLLVM_ENABLE_ASSERTIONS=ON From 6abcb7ce1729619e4fee63db27ccc32730f1b822 Mon Sep 17 00:00:00 2001 From: serge-sans-paille Date: Mon, 17 Feb 2020 13:42:00 +0100 Subject: [PATCH 13/14] Support -fuse-ld=lld for riscv Add a configure feature test to filter out tests that explicitly depend on platform linker. Differential Revision: https://reviews.llvm.org/D74704 --- clang/lib/Driver/ToolChains/RISCVToolchain.cpp | 2 +- clang/test/Driver/riscv32-toolchain.c | 5 +++++ clang/test/Driver/riscv64-toolchain.c | 5 +++++ clang/test/lit.site.cfg.py.in | 3 +++ 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/clang/lib/Driver/ToolChains/RISCVToolchain.cpp b/clang/lib/Driver/ToolChains/RISCVToolchain.cpp index 24c2b37c4b77..21106d003859 100644 --- a/clang/lib/Driver/ToolChains/RISCVToolchain.cpp +++ b/clang/lib/Driver/ToolChains/RISCVToolchain.cpp @@ -142,7 +142,7 @@ void RISCV::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("elf32lriscv"); } - std::string Linker = getToolChain().GetProgramPath(getShortName()); + std::string Linker = getToolChain().GetLinkerPath(); bool WantCRTs = !Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles); diff --git a/clang/test/Driver/riscv32-toolchain.c b/clang/test/Driver/riscv32-toolchain.c index 2ff3a585bda3..b83c9aafcbfc 100644 --- a/clang/test/Driver/riscv32-toolchain.c +++ b/clang/test/Driver/riscv32-toolchain.c @@ -1,8 +1,13 @@ // A basic clang -cc1 command-line, and simple environment check. +// REQUIRES: platform-linker // RUN: %clang %s -### -no-canonical-prefixes -target riscv32 2>&1 | FileCheck -check-prefix=CC1 %s // CC1: clang{{.*}} "-cc1" "-triple" "riscv32" +// Test interaction with -fuse-ld=lld, if lld is available. +// RUN: %clang %s -### -no-canonical-prefixes -target riscv32 -fuse-ld=lld 2>&1 | FileCheck -check-prefix=LLD %s +// LLD: {{(error: invalid linker name in argument '-fuse-ld=lld')|(ld.lld)}} + // In the below tests, --rtlib=platform is used so that the driver ignores // the configure-time CLANG_DEFAULT_RTLIB option when choosing the runtime lib diff --git a/clang/test/Driver/riscv64-toolchain.c b/clang/test/Driver/riscv64-toolchain.c index 42cac51de59e..a5cfc1242db7 100644 --- a/clang/test/Driver/riscv64-toolchain.c +++ b/clang/test/Driver/riscv64-toolchain.c @@ -1,8 +1,13 @@ // A basic clang -cc1 command-line, and simple environment check. +// REQUIRES: platform-linker // RUN: %clang %s -### -no-canonical-prefixes -target riscv64 2>&1 | FileCheck -check-prefix=CC1 %s // CC1: clang{{.*}} "-cc1" "-triple" "riscv64" +// Test interaction with -fuse-ld=lld, if lld is available. +// RUN: %clang %s -### -no-canonical-prefixes -target riscv32 -fuse-ld=lld 2>&1 | FileCheck -check-prefix=LLD %s +// LLD: {{(error: invalid linker name in argument '-fuse-ld=lld')|(ld.lld)}} + // In the below tests, --rtlib=platform is used so that the driver ignores // the configure-time CLANG_DEFAULT_RTLIB option when choosing the runtime lib diff --git a/clang/test/lit.site.cfg.py.in b/clang/test/lit.site.cfg.py.in index e9b35ac01771..1f37ad935bd4 100644 --- a/clang/test/lit.site.cfg.py.in +++ b/clang/test/lit.site.cfg.py.in @@ -46,5 +46,8 @@ except KeyError: import lit.llvm lit.llvm.initialize(lit_config, config) +if not "@CLANG_DEFAULT_LINKER@": + config.available_features('platform-linker') + # Let the main config do the real work. lit_config.load_config(config, "@CLANG_SOURCE_DIR@/test/lit.cfg.py") From e3f2df66eaf6e93e63fffcdc759cbd2fb43854d4 Mon Sep 17 00:00:00 2001 From: Arun Thomas Date: Thu, 26 Mar 2020 00:04:51 -0400 Subject: [PATCH 14/14] Use lld and compiler-rt --- Makefile.isp | 6 +- compiler-rt/.gitignore | 2 + compiler-rt/Makefile.isp | 63 +++++++++++++++++++ compiler-rt/lib/builtins/CMakeLists.txt | 5 ++ .../RISCV/MCTargetDesc/ISPELFStreamer.cpp | 2 - 5 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 compiler-rt/Makefile.isp diff --git a/Makefile.isp b/Makefile.isp index 795447c31b81..63e09918b896 100644 --- a/Makefile.isp +++ b/Makefile.isp @@ -15,18 +15,16 @@ endif BUILD_TYPE ?= debug COMMON_CMAKE_FLAGS += -G "Ninja" -COMMON_CMAKE_FLAGS += -DLLVM_ENABLE_PROJECTS="clang" +COMMON_CMAKE_FLAGS += -DLLVM_ENABLE_PROJECTS="clang;lld;llvm" COMMON_CMAKE_FLAGS += -DCMAKE_MAKE_PROGRAM=$(NINJA) COMMON_CMAKE_FLAGS += -DCMAKE_INSTALL_PREFIX=$(ISP_PREFIX) COMMON_CMAKE_FLAGS += -DCMAKE_C_COMPILER=clang COMMON_CMAKE_FLAGS += -DCMAKE_CXX_COMPILER=clang++ -COMMON_CMAKE_FLAGS += -DLLVM_BINUTILS_INCDIR=/usr/include COMMON_CMAKE_FLAGS += -DBUILD_SHARED_LIBS=True COMMON_CMAKE_FLAGS += -DLLVM_OPTIMIZED_TABLEGEN=True COMMON_CMAKE_FLAGS += -DLLVM_BUILD_TESTS=True -COMMON_CMAKE_FLAGS += -DDEFAULT_SYSROOT=$(ISP_PREFIX)/riscv64-unknown-elf -COMMON_CMAKE_FLAGS += -DLLVM_DEFAULT_TARGET_TRIPLE="riscv64-unknown-elf" COMMON_CMAKE_FLAGS += -DLLVM_TARGETS_TO_BUILD="RISCV" +COMMON_CMAKE_FLAGS += -DCLANG_DEFAULT_RTLIB=compiler-rt DEBUG_CMAKE_FLAGS := -DCMAKE_BUILD_TYPE=Debug DEBUG_CMAKE_FLAGS += -DLLVM_ENABLE_ASSERTIONS=ON diff --git a/compiler-rt/.gitignore b/compiler-rt/.gitignore index f7d4697ebc5f..5eaa535e91ed 100644 --- a/compiler-rt/.gitignore +++ b/compiler-rt/.gitignore @@ -4,3 +4,5 @@ clang_darwin multi_arch *.sw? *.pyc +build32 +build64 diff --git a/compiler-rt/Makefile.isp b/compiler-rt/Makefile.isp new file mode 100644 index 000000000000..814c89790957 --- /dev/null +++ b/compiler-rt/Makefile.isp @@ -0,0 +1,63 @@ +.PHONY: all +.PHONY: install +.PHONY: clean +.PHONY: rv32 rv64 + +NINJA := ninja + +COMMON_FLAGS += -G "Ninja" +COMMON_FLAGS += -DCMAKE_C_COMPILER=$(ISP_PREFIX)/bin/clang +COMMON_FLAGS += -DCMAKE_CXX_COMPILER=$(ISP_PREFIX)/bin/clang++ +COMMON_FLAGS += -DCMAKE_AR=$(ISP_PREFIX)/bin/llvm-ar +COMMON_FLAGS += -DCMAKE_NM=$(ISP_PREFIX)/bin/llvm-nm +COMMON_FLAGS += -DCMAKE_RANLIB=$(ISP_PREFIX)/bin/llvm-ranlib +COMMON_FLAGS += -DCMAKE_INSTALL_PREFIX=$(ISP_PREFIX) +COMMON_FLAGS += -DCMAKE_VERBOSE_MAKEFILE=ON +COMMON_FLAGS += -DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=lld" +COMMON_FLAGS += -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY +COMMON_FLAGS += -DCOMPILER_RT_OS_DIR=baremetal -DCOMPILER_RT_BAREMETAL_BUILD=ON +COMMON_FLAGS += -DCOMPILER_RT_BUILD_SANITIZERS=OFF -DCOMPILER_RT_BUILD_XRAY=OFF +COMMON_FLAGS += -DCOMPILER_RT_BUILD_LIBFUZZER=OFF -DCOMPILER_RT_BUILD_PROFILE=OFF + +RV32_TARGET_FLAGS += --target=riscv32-unknown-elf -march=rv32ima -mabi=ilp32 +RV32_TARGET_FLAGS += -mno-relax +RV32_FLAGS += -DCMAKE_C_FLAGS=$(RV32_TARGET_FLAGS) +RV32_FLAGS += -DCMAKE_CXX_FLAGS=$(RV32_TARGET_FLAGS) +RV32_FLAGS += -DCMAKE_ASM_FLAGS=$(RV32_TARGET_FLAGS) +RV32_FLAGS += -DCOMPILER_RT_DEFAULT_TARGET_ARCH=riscv32 +RV32_FLAGS += -DCOMPILER_RT_DEFAULT_TARGET_TRIPLE=riscv32-unknown-elf +RV32_FLAGS += -DCMAKE_SYSROOT=$(ISP_PREFIX)/clang_sysroot/riscv32-unknown-elf + +RV64_TARGET_FLAGS += --target=riscv64-unknown-elf -march=rv64imafd -mabi=lp64d +RV64_TARGET_FLAGS += -mno-relax -mcmodel=medany +RV64_FLAGS += -DCMAKE_C_FLAGS=$(RV64_TARGET_FLAGS) +RV64_FLAGS += -DCMAKE_CXX_FLAGS=$(RV64_TARGET_FLAGS) +RV64_FLAGS += -DCMAKE_ASM_FLAGS=$(RV64_TARGET_FLAGS) +RV64_FLAGS += -DCOMPILER_RT_DEFAULT_TARGET_ARCH=riscv64 +RV64_FLAGS += -DCOMPILER_RT_DEFAULT_TARGET_TRIPLE=riscv64-unknown-elf +RV64_FLAGS += -DCMAKE_SYSROOT=$(ISP_PREFIX)/clang_sysroot/riscv64-unknown-elf + +all: rv32 rv64 + +rv32: build32/build.ninja + $(NINJA) -v -C build32 + +rv64: build64/build.ninja + $(NINJA) -v -C build64 + +build32/build.ninja: + mkdir -p build32 + cd build32; cmake $(COMMON_FLAGS) $(RV32_FLAGS) .. + +build64/build.ninja: + mkdir -p build64 + cd build64; cmake $(COMMON_FLAGS) $(RV64_FLAGS) .. + +install: + $(NINJA) -v -C build32 install + $(NINJA) -v -C build64 install + mkdir -p $(ISP_PREFIX)/lib/clang/11.0.0/lib + cp $(ISP_PREFIX)/lib/baremetal/* $(ISP_PREFIX)/lib/clang/11.0.0/lib + +clean: + $(RM) -r build32 build64 diff --git a/compiler-rt/lib/builtins/CMakeLists.txt b/compiler-rt/lib/builtins/CMakeLists.txt index 125a3a1b1476..00210ef3c979 100644 --- a/compiler-rt/lib/builtins/CMakeLists.txt +++ b/compiler-rt/lib/builtins/CMakeLists.txt @@ -645,7 +645,12 @@ else () # double routines. if("${arch}" STREQUAL "riscv32") list(APPEND BUILTIN_CFLAGS -fforce-enable-int128) + list(APPEND BUILTIN_CFLAGS -march=rv32ima -mabi=ilp32) endif() + if("${arch}" STREQUAL "riscv64") + list(APPEND BUILTIN_CFLAGS -march=rv64imafd -mabi=lp64d) + endif() + list(APPEND BUILTIN_CFLAGS -mno-relax) add_compiler_rt_runtime(clang_rt.builtins STATIC diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/ISPELFStreamer.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/ISPELFStreamer.cpp index dddd5dbde8cf..4d62253dd88e 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/ISPELFStreamer.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/ISPELFStreamer.cpp @@ -37,8 +37,6 @@ void ISPTargetELFStreamer::EmitSSITHMetadataHeader(MCObjectStreamer &Streamer){ SmallString<256> Code; raw_svector_ostream VecOS(Code); - printf("emitting metadata header!\n"); - //Emit the Metadata tag uint8_t MD = DMD_SET_BASE_ADDRESS_OP; support::endian::write(VecOS, MD, support::little);