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/clang-tools-extra/clang-tidy-vs/ClangTidy/packages.config b/clang-tools-extra/clang-tidy-vs/ClangTidy/packages.config index 75d7fafcf20d..8e93c060cb28 100644 --- a/clang-tools-extra/clang-tidy-vs/ClangTidy/packages.config +++ b/clang-tools-extra/clang-tidy-vs/ClangTidy/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file 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 diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h index 0307f8f67298..8f1776d59cc7 100644 --- a/llvm/include/llvm/CodeGen/AsmPrinter.h +++ b/llvm/include/llvm/CodeGen/AsmPrinter.h @@ -410,6 +410,12 @@ class AsmPrinter : public MachineFunctionPass { llvm_unreachable("EmitInstruction not implemented"); } + //SSITH Placeholder, only used by RISCV currently + virtual void EmitSSITHMetadataInst(MCSymbol *Sym, const MCSubtargetInfo &STI, + uint8_t tag){} + virtual void EmitSSITHMetadataFnRange(MCSymbol *begin, MCSymbol *end, + const MCSubtargetInfo &STI) {} + /// Return the symbol for the specified constant pool entry. virtual MCSymbol *GetCPISymbol(unsigned CPID) const; diff --git a/llvm/include/llvm/CodeGen/MachineInstr.h b/llvm/include/llvm/CodeGen/MachineInstr.h index a85fee7bf4b3..5b06d7c762ad 100644 --- a/llvm/include/llvm/CodeGen/MachineInstr.h +++ b/llvm/include/llvm/CodeGen/MachineInstr.h @@ -102,9 +102,16 @@ class MachineInstr // no unsigned wrap. NoSWrap = 1 << 12, // Instruction supports binary operator // no signed wrap. - IsExact = 1 << 13 // Instruction supports division is - // known to be exact. + IsExact = 1 << 13, // Instruction supports division is + //SSITH + FnProlog = 1 << 14, // Instruction is part of the compiler generated + // prolog + FnEpilog = 1 << 15, // Instruction is part of the compiler generated + // epilog + FPtrStore = 1 << 16, // Instruction writes a function pointer to memory + FPtrCreate = 1 << 17 // Instruction creates a function pointer }; + //SSITH NOTE: Flags is only 16 bits long, getting close to the max here private: const MCInstrDesc *MCID; // Instruction descriptor. @@ -116,7 +123,7 @@ class MachineInstr using OperandCapacity = ArrayRecycler::Capacity; OperandCapacity CapOperands; // Capacity of the Operands array. - uint16_t Flags = 0; // Various bits of additional + uint32_t Flags = 0; // Various bits of additional // information about machine // instruction. @@ -286,7 +293,7 @@ class MachineInstr } /// Return the MI flags bitvector. - uint16_t getFlags() const { + uint32_t getFlags() const { return Flags; } @@ -297,7 +304,7 @@ class MachineInstr /// Set a MI flag. void setFlag(MIFlag Flag) { - Flags |= (uint16_t)Flag; + Flags |= (uint32_t)Flag; } void setFlags(unsigned flags) { @@ -308,7 +315,7 @@ class MachineInstr /// clearFlag - Clear a MI flag. void clearFlag(MIFlag Flag) { - Flags &= ~((uint16_t)Flag); + Flags &= ~((uint32_t)Flag); } /// Return true if MI is in a bundle (but not the first MI in a bundle). @@ -1551,7 +1558,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; + uint32_t mergeFlagsWith(const MachineInstr& Other) const; static uint16_t copyFlagsFromInstruction(const Instruction &I); diff --git a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h index 4bf37b631bdb..8129df78673d 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h @@ -367,6 +367,8 @@ struct SDNodeFlags { bool AllowContract : 1; bool ApproximateFuncs : 1; bool AllowReassociation : 1; + bool FPtrCreate : 1; + bool FPtrStore : 1; public: /// Default constructor turns off all optimization flags. @@ -375,7 +377,7 @@ struct SDNodeFlags { Exact(false), NoNaNs(false), NoInfs(false), NoSignedZeros(false), AllowReciprocal(false), VectorReduction(false), AllowContract(false), ApproximateFuncs(false), - AllowReassociation(false) {} + AllowReassociation(false), FPtrCreate(false), FPtrStore(false) {} /// Propagate the fast-math-flags from an IR FPMathOperator. void copyFMF(const FPMathOperator &FPMO) { @@ -438,6 +440,14 @@ struct SDNodeFlags { setDefined(); AllowReassociation = b; } + void setFPtrCreate(bool b) { + setDefined(); + FPtrCreate = b; + } + void setFPtrStore(bool b) { + setDefined(); + FPtrStore = b; + } // These are accessors for each flag. bool hasNoUnsignedWrap() const { return NoUnsignedWrap; } @@ -451,6 +461,8 @@ struct SDNodeFlags { bool hasAllowContract() const { return AllowContract; } bool hasApproximateFuncs() const { return ApproximateFuncs; } bool hasAllowReassociation() const { return AllowReassociation; } + bool hasFPtrCreate() const { return FPtrCreate; } + bool hasFPtrStore() const { return FPtrStore; } bool isFast() const { return NoSignedZeros && AllowReciprocal && NoNaNs && NoInfs && @@ -473,6 +485,8 @@ struct SDNodeFlags { AllowContract &= Flags.AllowContract; ApproximateFuncs &= Flags.ApproximateFuncs; AllowReassociation &= Flags.AllowReassociation; + FPtrCreate &= Flags.FPtrCreate; + FPtrStore &= Flags.FPtrStore; } }; diff --git a/llvm/include/llvm/CodeGen/TargetInstrInfo.h b/llvm/include/llvm/CodeGen/TargetInstrInfo.h index b732be625de5..0127ce4f31e1 100644 --- a/llvm/include/llvm/CodeGen/TargetInstrInfo.h +++ b/llvm/include/llvm/CodeGen/TargetInstrInfo.h @@ -887,7 +887,8 @@ class TargetInstrInfo : public MCInstrInfo { MachineBasicBlock::iterator MI, unsigned 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!"); } @@ -899,7 +900,8 @@ class TargetInstrInfo : public MCInstrInfo { MachineBasicBlock::iterator MI, unsigned 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/MCELFStreamer.h b/llvm/include/llvm/MC/MCELFStreamer.h index 8838d53d75b5..a63f9ef1c639 100644 --- a/llvm/include/llvm/MC/MCELFStreamer.h +++ b/llvm/include/llvm/MC/MCELFStreamer.h @@ -82,7 +82,15 @@ class MCELFStreamer : public MCObjectStreamer { bool isBundleLocked() const; void EmitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &) override; void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &) override; - + + //SSITH + void EmitSSITHMetadataHeader(const MCSubtargetInfo &STI) override; + void EmitSSITHMetadataEntry(SmallVector &Fixups, + const MCSubtargetInfo &STI, + uint8_t MD_type, uint8_t tag) override; + char *SSITHpopLastInstruction(int nbytes) override; + void SSITHpushInstruction(char *inst, int nbytes) override; + void fixSymbolsInTLSFixups(const MCExpr *expr); void finalizeCGProfileEntry(const MCSymbolRefExpr *&S); void finalizeCGProfile(); diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h index 67284fb379f3..0fad4586c7cd 100644 --- a/llvm/include/llvm/MC/MCStreamer.h +++ b/llvm/include/llvm/MC/MCStreamer.h @@ -583,6 +583,14 @@ class MCStreamer { uint64_t Size = 0, unsigned ByteAlignment = 0, SMLoc Loc = SMLoc()) = 0; + /// SSITH metadata write - only defined by MCELFStreamer + virtual void EmitSSITHMetadataHeader(const MCSubtargetInfo &STI) {} + virtual void EmitSSITHMetadataEntry(SmallVector &Fixups, + const MCSubtargetInfo &STI, + uint8_t MD_type, uint8_t tag) {} + virtual char *SSITHpopLastInstruction(int nbytes) { return nullptr; } + virtual void SSITHpushInstruction(char *inst, int nbytes) {} + /// Emit a thread local bss (.tbss) symbol. /// /// \param Section - The thread local common section. diff --git a/llvm/include/llvm/MC/SSITHMetadata.h b/llvm/include/llvm/MC/SSITHMetadata.h new file mode 100755 index 000000000000..96eb9edfd2cd --- /dev/null +++ b/llvm/include/llvm/MC/SSITHMetadata.h @@ -0,0 +1,152 @@ +/* + * 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 + +/* 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: + */ +#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 +#endif diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index d34254699ed5..0598a3e5acf0 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -99,6 +99,7 @@ #include "llvm/MC/MCTargetOptions.h" #include "llvm/MC/MCValue.h" #include "llvm/MC/SectionKind.h" +#include "llvm/MC/SSITHMetadata.h" #include "llvm/Pass.h" #include "llvm/Remarks/Remark.h" #include "llvm/Support/Casting.h" @@ -1034,19 +1035,52 @@ void AsmPrinter::EmitFunctionBody() { MLI = OwnedMLI.get(); } } + //SSITH + MCContext &Context = getObjFileLowering().getContext(); + MCSectionELF *ISP = Context.getELFSection(".dover_metadata", ELF::SHT_PROGBITS, 0); + + //Gen tag info needs this to happen first or it fails + if(!ISP->hasInstructions()){ + OutStreamer->PushSection(); + OutStreamer->SwitchSection(ISP); + OutStreamer->EmitSSITHMetadataHeader(getSubtargetInfo()); + ISP->setHasInstructions(true); + OutStreamer->PopSection(); + } // Print out code for the function. bool HasAnyRealCode = false; int NumInstsInFunction = 0; + + //MF->dump(); + //errs() << "\n\n"; + for (auto &MBB : *MF) { // Print a label for the basic block. EmitBasicBlockStart(MBB); + + //errs() << "-------------\n"; + //SSITH + OutStreamer->PushSection(); + OutStreamer->SwitchSection(ISP); + EmitSSITHMetadataInst(MBB.getSymbol(), getSubtargetInfo(), DMT_BRANCH_VALID_TGT); + OutStreamer->PopSection(); + + //MBB.getSymbol()->dump(); + //MBB.dump(); + for (auto &MI : MBB) { - // Print the assembly for the instruction. if (!MI.isPosition() && !MI.isImplicitDef() && !MI.isKill() && !MI.isDebugInstr()) { HasAnyRealCode = true; ++NumInstsInFunction; + //SSITH + if(NumInstsInFunction == 1){ + OutStreamer->PushSection(); + OutStreamer->SwitchSection(ISP); + EmitSSITHMetadataInst(CurrentFnSym, getSubtargetInfo(), DMT_CFI3L_VALID_TGT); + OutStreamer->PopSection(); + } } // If there is a pre-instruction symbol, emit a label for it here. @@ -1120,6 +1154,7 @@ void AsmPrinter::EmitFunctionBody() { EmitBasicBlockEnd(MBB); } + EmittedInsts += NumInstsInFunction; MachineOptimizationRemarkAnalysis R(DEBUG_TYPE, "InstructionCount", MF->getFunction().getSubprogram(), @@ -1171,6 +1206,13 @@ void AsmPrinter::EmitFunctionBody() { OutStreamer->EmitLabel(CurrentFnEnd); } + //SSITH -- add in function range tag + //NOTE - Now doing this in RISCVAsmPrinter when we find the return inst + //OutStreamer->PushSection(); + //OutStreamer->SwitchSection(ISP); + //EmitSSITHMetadataFnRange(CurrentFnSym, CurrentFnEnd, getSubtargetInfo()); + //OutStreamer->PopSection(); + // If the target wants a .size directive for the size of the function, emit // it. if (MAI->hasDotTypeDotSizeDirective()) { @@ -2927,19 +2969,21 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock &MBB) const { } // 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/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp index 26d58340b618..abd6a70e4945 100644 --- a/llvm/lib/CodeGen/MachineInstr.cpp +++ b/llvm/lib/CodeGen/MachineInstr.cpp @@ -513,7 +513,7 @@ void MachineInstr::setPostInstrSymbol(MachineFunction &MF, MCSymbol *Symbol) { MF.createMIExtraInfo(memoperands(), getPreInstrSymbol(), Symbol)); } -uint16_t MachineInstr::mergeFlagsWith(const MachineInstr &Other) const { +uint32_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(); @@ -1531,6 +1531,12 @@ void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST, OS << "nsw "; if (getFlag(MachineInstr::IsExact)) OS << "exact "; + if (getFlag(MachineInstr::FnProlog)) + OS << "ssith-prolog "; + if (getFlag(MachineInstr::FnEpilog)) + OS << "ssith-epilog "; + if (getFlag(MachineInstr::FPtrStore)) + OS << "ssith-fptr-store "; // Print the opcode name. if (TII) diff --git a/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/llvm/lib/CodeGen/PrologEpilogInserter.cpp index 67834c8c352a..bec1608639d7 100644 --- a/llvm/lib/CodeGen/PrologEpilogInserter.cpp +++ b/llvm/lib/CodeGen/PrologEpilogInserter.cpp @@ -543,7 +543,7 @@ static void insertCSRSaves(MachineBasicBlock &SaveBlock, unsigned Reg = CS.getReg(); const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); TII.storeRegToStackSlot(SaveBlock, I, Reg, true, CS.getFrameIdx(), RC, - TRI); + TRI, MachineInstr::FnProlog); } } } @@ -564,7 +564,8 @@ static void insertCSRRestores(MachineBasicBlock &RestoreBlock, for (const CalleeSavedInfo &CI : reverse(CSI)) { unsigned Reg = CI.getReg(); 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/CodeGen/SelectionDAG/InstrEmitter.cpp b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp index 059e5f7c8dd3..9c0572be0493 100644 --- a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp @@ -861,6 +861,24 @@ EmitMachineNode(SDNode *Node, bool IsClone, bool IsCloned, // Create the new machine instruction. MachineInstrBuilder MIB = BuildMI(*MF, Node->getDebugLoc(), II); + + //SSITH TODO - Tag the new instruction + if(isa(Node)) + errs() << "storesdnode in instremitter\n"; + + SDNodeFlags Flags = Node->getFlags(); + if(Flags.hasFPtrCreate()){ + MIB.getInstr()->setFlag(MachineInstr::FPtrCreate); + } + else if(Flags.hasFPtrStore()){ + MIB.getInstr()->setFlag(MachineInstr::FPtrStore); + //errs() << "fptr store in instremitter\n"; + //Node->dump(); + //errs() << Node << "\n"; + //if(Node->isMachineOpcode()) + // errs() << "has machine opcode\n"; + //errs() << "--------------\n"; + } // Add result register values for things that are defined by this // instruction. @@ -925,6 +943,11 @@ EmitMachineNode(SDNode *Node, bool IsClone, bool IsCloned, // happen before any custom inserter hook is called so that the // hook knows where in the block to insert the replacement code. MBB->insert(InsertPos, MIB); + + //SSITH - MBB insert seems to do a fair amount to the MI + //MIB.getInstr()->dump(); + //errs() << "\n"; + //errs() << "\n"; // The MachineInstr may also define physregs instead of virtregs. These // physreg values can reach other instructions in different ways: diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 5689a152ca55..0e11931fba94 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -1367,13 +1367,15 @@ SDValue SelectionDAG::getGlobalAddress(const GlobalValue *GV, const SDLoc &DL, ID.AddInteger(Offset); ID.AddInteger(TargetFlags); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP)) + if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP)){ return SDValue(E, 0); + } auto *N = newSDNode( Opc, DL.getIROrder(), DL.getDebugLoc(), GV, VT, Offset, TargetFlags); CSEMap.InsertNode(N, IP); InsertNode(N); + return SDValue(N, 0); } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 818f1ada04bc..16350d6de27a 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -1076,9 +1076,29 @@ void SelectionDAGBuilder::visit(const Instruction &I) { ++SDNodeOrder; CurInst = &I; - visit(I.getOpcode(), I); + //SSITH + SDValue Root = getRoot(); + const StoreInst *si = dyn_cast(CurInst); + if(si){ + Type *Ty = si->getValueOperand()->getType(); + if (PointerType *PtrTy = dyn_cast(Ty)){ + if(PtrTy->getElementType()->isFunctionTy()){ + SDNodeFlags Flags = Root.getNode()->getFlags(); + Flags.setFPtrStore(true); + Root.getNode()->setFlags(Flags); + //errs() << "fptr store\n"; + //Root.getNode()->dump(); + + //if(isa(Root.getNode())) + // errs() << "is a StoreSDNode\n"; + //if(Root.getNode()->isMachineOpcode()) + // errs() << "has machine opcode\n"; + } + } + } + if (auto *FPMO = dyn_cast(&I)) { // Propagate the fast-math-flags of this IR instruction to the DAG node that // maps to this instruction. @@ -1393,6 +1413,14 @@ SDValue SelectionDAGBuilder::getValue(const Value *V) { SDValue Val = getValueImpl(V); NodeMap[V] = Val; resolveDanglingDebugInfo(V, Val); + + //SSITH + //PointerType *ptr_t = dyn_cast(V->getType()); + //if(ptr_t && ptr_t->getElementType()->isFunctionTy()){ + // SDNodeFlags Flags = Val.getNode()->getFlags(); + // Flags.setFPtrStore(true); + // Val.getNode()->setFlags(Flags); + //} return Val; } @@ -4211,6 +4239,9 @@ void SelectionDAGBuilder::visitStore(const StoreInst &I) { SDValue StoreNode = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, makeArrayRef(Chains.data(), ChainI)); + + + DAG.setRoot(StoreNode); } diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp index 6fe16abd5a3a..22dc165cf016 100644 --- a/llvm/lib/MC/MCELFStreamer.cpp +++ b/llvm/lib/MC/MCELFStreamer.cpp @@ -10,6 +10,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/MC/SSITHMetadata.h" #include "llvm/MC/MCELFStreamer.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" @@ -498,6 +499,88 @@ void MCELFStreamer::EmitInstToFragment(const MCInst &Inst, fixSymbolsInTLSFixups(F.getFixups()[i].getValue()); } +//SSITH Addition +void MCELFStreamer::EmitSSITHMetadataHeader(const MCSubtargetInfo &STI){ + SmallString<256> Code; + raw_svector_ostream VecOS(Code); + MCDataFragment *DF; + + //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); + + DF = getOrCreateDataFragment(); + DF->setHasInstructions(STI); + DF->getContents().append(Code.begin(), Code.end()); +} + +//SSITH Addition +void MCELFStreamer::EmitSSITHMetadataEntry(SmallVector &Fixups, + const MCSubtargetInfo &STI, + uint8_t MD_type, uint8_t tag){ + SmallString<256> Code; + raw_svector_ostream VecOS(Code); + MCDataFragment *DF; + + //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 = getOrCreateDataFragment(&STI); + // 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->setHasInstructions(STI); + DF->getContents().append(Code.begin(), Code.end()); +} + +//SSITH Addition +char *MCELFStreamer::SSITHpopLastInstruction(int nbytes){ + char *buf = new char[4]; + MCDataFragment *DF = dyn_cast(getCurrentFragment()); + assert(DF && "[ssith] bad fragment type\n"); + + SmallVectorImpl &Contents = DF->getContents(); + for(int i = 0; i < nbytes; i++) + buf[i] = Contents.pop_back_val(); + + return buf; +} + +//SSITH Addition +void MCELFStreamer::SSITHpushInstruction(char *inst, int nbytes){ + MCDataFragment *DF = dyn_cast(getCurrentFragment()); + assert(DF && "[ssith] bad fragment type\n"); + + for(int i = nbytes - 1; i >= 0; i--) + DF->getContents().push_back(inst[i]); + + delete inst; +} + // A fragment can only have one Subtarget, and when bundling is enabled we // sometimes need to use the same fragment. We give an error if there // are conflicting Subtargets. diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.h b/llvm/lib/Target/AArch64/AArch64InstrInfo.h index 148b7afabe69..459435b7c6bd 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.h +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.h @@ -142,12 +142,14 @@ class AArch64InstrInfo final : public AArch64GenInstrInfo { MachineBasicBlock::iterator MBBI, unsigned 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, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const override; + const TargetRegisterInfo *TRI, + unsigned flags = 0) const override; // This tells target independent code that it is okay to pass instructions // with subreg operands to foldMemoryOperandImpl. diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp index 45b0a5b2a8d7..9fb1a53fc4b9 100644 --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp @@ -894,7 +894,8 @@ void SIInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const { + const TargetRegisterInfo *TRI, + unsigned flags) const { MachineFunction *MF = MBB.getParent(); SIMachineFunctionInfo *MFI = MF->getInfo(); MachineFrameInfo &FrameInfo = MF->getFrameInfo(); @@ -1001,7 +1002,8 @@ void SIInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const { + const TargetRegisterInfo *TRI, + unsigned flags) const { MachineFunction *MF = MBB.getParent(); SIMachineFunctionInfo *MFI = MF->getInfo(); MachineFrameInfo &FrameInfo = MF->getFrameInfo(); diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.h b/llvm/lib/Target/AMDGPU/SIInstrInfo.h index 13e3dbd3cfe7..b2bb6cebce1d 100644 --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.h +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.h @@ -211,12 +211,14 @@ class SIInstrInfo final : public AMDGPUGenInstrInfo { MachineBasicBlock::iterator MI, unsigned 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 MI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const override; + const TargetRegisterInfo *TRI, + unsigned flags = 0) const override; bool expandPostRAPseudo(MachineInstr &MI) const override; diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.h b/llvm/lib/Target/ARM/ARMBaseInstrInfo.h index 24c11e437936..a87c89fa6b46 100644 --- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.h +++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.h @@ -210,13 +210,15 @@ class ARMBaseInstrInfo : public ARMGenInstrInfo { MachineBasicBlock::iterator MBBI, unsigned 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, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const override; + const TargetRegisterInfo *TRI, + unsigned flags = 0) const override; bool expandPostRAPseudo(MachineInstr &MI) const override; diff --git a/llvm/lib/Target/ARM/Thumb1InstrInfo.cpp b/llvm/lib/Target/ARM/Thumb1InstrInfo.cpp index f57d93a2e83d..973fe617260f 100644 --- a/llvm/lib/Target/ARM/Thumb1InstrInfo.cpp +++ b/llvm/lib/Target/ARM/Thumb1InstrInfo.cpp @@ -78,7 +78,8 @@ void Thumb1InstrInfo:: storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned SrcReg, bool isKill, int FI, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const { + const TargetRegisterInfo *TRI, + unsigned flags) const { assert((RC == &ARM::tGPRRegClass || (TargetRegisterInfo::isPhysicalRegister(SrcReg) && isARMLowRegister(SrcReg))) && "Unknown regclass!"); @@ -107,7 +108,8 @@ void Thumb1InstrInfo:: loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned DestReg, int FI, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const { + const TargetRegisterInfo *TRI, + unsigned flags) const { assert((RC->hasSuperClassEq(&ARM::tGPRRegClass) || (TargetRegisterInfo::isPhysicalRegister(DestReg) && isARMLowRegister(DestReg))) && "Unknown regclass!"); diff --git a/llvm/lib/Target/ARM/Thumb1InstrInfo.h b/llvm/lib/Target/ARM/Thumb1InstrInfo.h index bc433e7a7a93..6d6d584a6ace 100644 --- a/llvm/lib/Target/ARM/Thumb1InstrInfo.h +++ b/llvm/lib/Target/ARM/Thumb1InstrInfo.h @@ -44,13 +44,15 @@ class Thumb1InstrInfo : public ARMBaseInstrInfo { MachineBasicBlock::iterator MBBI, unsigned 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, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const override; + const TargetRegisterInfo *TRI, + unsigned flags = 0) const override; bool canCopyGluedNodeDuringSchedule(SDNode *N) const override; private: diff --git a/llvm/lib/Target/ARM/Thumb2InstrInfo.cpp b/llvm/lib/Target/ARM/Thumb2InstrInfo.cpp index 6ddd71cf8d3e..8835dc31aac1 100644 --- a/llvm/lib/Target/ARM/Thumb2InstrInfo.cpp +++ b/llvm/lib/Target/ARM/Thumb2InstrInfo.cpp @@ -135,7 +135,8 @@ void Thumb2InstrInfo:: storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned 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(); @@ -178,7 +179,8 @@ void Thumb2InstrInfo:: loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned DestReg, int FI, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const { + const TargetRegisterInfo *TRI, + unsigned flags) const { MachineFunction &MF = *MBB.getParent(); MachineFrameInfo &MFI = MF.getFrameInfo(); MachineMemOperand *MMO = MF.getMachineMemOperand( diff --git a/llvm/lib/Target/ARM/Thumb2InstrInfo.h b/llvm/lib/Target/ARM/Thumb2InstrInfo.h index c5aca82acc26..081dcceb3dd5 100644 --- a/llvm/lib/Target/ARM/Thumb2InstrInfo.h +++ b/llvm/lib/Target/ARM/Thumb2InstrInfo.h @@ -46,13 +46,15 @@ class Thumb2InstrInfo : public ARMBaseInstrInfo { MachineBasicBlock::iterator MBBI, unsigned 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, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const override; + const TargetRegisterInfo *TRI, + unsigned flags = 0) const override; /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As /// such, whenever a client has an instance of instruction info, it should diff --git a/llvm/lib/Target/BPF/BPFInstrInfo.cpp b/llvm/lib/Target/BPF/BPFInstrInfo.cpp index 932f718d5490..659c11d85927 100644 --- a/llvm/lib/Target/BPF/BPFInstrInfo.cpp +++ b/llvm/lib/Target/BPF/BPFInstrInfo.cpp @@ -125,7 +125,8 @@ void BPFInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned 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(); @@ -148,7 +149,8 @@ void BPFInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned DestReg, int FI, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const { + const TargetRegisterInfo *TRI, + unsigned flags) const { DebugLoc DL; if (I != MBB.end()) DL = I->getDebugLoc(); diff --git a/llvm/lib/Target/BPF/BPFInstrInfo.h b/llvm/lib/Target/BPF/BPFInstrInfo.h index e4bd757da560..b7a721aabe4d 100644 --- a/llvm/lib/Target/BPF/BPFInstrInfo.h +++ b/llvm/lib/Target/BPF/BPFInstrInfo.h @@ -39,12 +39,15 @@ class BPFInstrInfo : public BPFGenInstrInfo { MachineBasicBlock::iterator MBBI, unsigned 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, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const override; + const TargetRegisterInfo *TRI, + unsigned flags = 0) const override; + bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl &Cond, diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp index 3ecb14282137..15b0c68fd040 100644 --- a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp +++ b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp @@ -873,7 +873,8 @@ void HexagonInstrInfo::copyPhysReg(MachineBasicBlock &MBB, void HexagonInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned SrcReg, bool isKill, int FI, - const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const { + const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, + unsigned flags) const { DebugLoc DL = MBB.findDebugLoc(I); MachineFunction &MF = *MBB.getParent(); MachineFrameInfo &MFI = MF.getFrameInfo(); @@ -939,7 +940,8 @@ void HexagonInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, void HexagonInstrInfo::loadRegFromStackSlot( MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned DestReg, int FI, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const { + const TargetRegisterInfo *TRI, + unsigned flags) const { DebugLoc DL = MBB.findDebugLoc(I); MachineFunction &MF = *MBB.getParent(); MachineFrameInfo &MFI = MF.getFrameInfo(); diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfo.h b/llvm/lib/Target/Hexagon/HexagonInstrInfo.h index 688af2a90895..461e9dbac854 100644 --- a/llvm/lib/Target/Hexagon/HexagonInstrInfo.h +++ b/llvm/lib/Target/Hexagon/HexagonInstrInfo.h @@ -195,7 +195,8 @@ class HexagonInstrInfo : public HexagonGenInstrInfo { MachineBasicBlock::iterator MBBI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const override; + const TargetRegisterInfo *TRI, + unsigned flags = 0) const override; /// Load the specified register of the given register class from the specified /// stack frame index. The load instruction is to be added to the given @@ -204,7 +205,8 @@ class HexagonInstrInfo : public HexagonGenInstrInfo { MachineBasicBlock::iterator MBBI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const override; + const TargetRegisterInfo *TRI, + unsigned flags = 0) const override; /// This function is called for all pseudo instructions /// that remain after register allocation. Many pseudo instructions are diff --git a/llvm/lib/Target/Lanai/LanaiInstrInfo.cpp b/llvm/lib/Target/Lanai/LanaiInstrInfo.cpp index 93db67c4e3eb..37844bdb0e18 100644 --- a/llvm/lib/Target/Lanai/LanaiInstrInfo.cpp +++ b/llvm/lib/Target/Lanai/LanaiInstrInfo.cpp @@ -50,7 +50,8 @@ void LanaiInstrInfo::storeRegToStackSlot( MachineBasicBlock &MBB, MachineBasicBlock::iterator Position, unsigned SourceRegister, bool IsKill, int FrameIndex, const TargetRegisterClass *RegisterClass, - const TargetRegisterInfo * /*RegisterInfo*/) const { + const TargetRegisterInfo * /*RegisterInfo*/, + unsigned flags) const { DebugLoc DL; if (Position != MBB.end()) { DL = Position->getDebugLoc(); @@ -70,7 +71,8 @@ void LanaiInstrInfo::loadRegFromStackSlot( MachineBasicBlock &MBB, MachineBasicBlock::iterator Position, unsigned DestinationRegister, int FrameIndex, const TargetRegisterClass *RegisterClass, - const TargetRegisterInfo * /*RegisterInfo*/) const { + const TargetRegisterInfo * /*RegisterInfo*/, + unsigned flags) const { DebugLoc DL; if (Position != MBB.end()) { DL = Position->getDebugLoc(); diff --git a/llvm/lib/Target/Lanai/LanaiInstrInfo.h b/llvm/lib/Target/Lanai/LanaiInstrInfo.h index feda529610c8..e2b8ecdc9585 100644 --- a/llvm/lib/Target/Lanai/LanaiInstrInfo.h +++ b/llvm/lib/Target/Lanai/LanaiInstrInfo.h @@ -56,14 +56,16 @@ class LanaiInstrInfo : public LanaiGenInstrInfo { MachineBasicBlock::iterator Position, unsigned SourceRegister, bool IsKill, int FrameIndex, const TargetRegisterClass *RegisterClass, - const TargetRegisterInfo *RegisterInfo) const override; + const TargetRegisterInfo *RegisterInfo, + unsigned flags = 0) const override; void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator Position, unsigned DestinationRegister, int FrameIndex, const TargetRegisterClass *RegisterClass, - const TargetRegisterInfo *RegisterInfo) const override; + const TargetRegisterInfo *RegisterInfo, + unsigned flags = 0) const override; bool expandPostRAPseudo(MachineInstr &MI) const override; diff --git a/llvm/lib/Target/MSP430/MSP430InstrInfo.cpp b/llvm/lib/Target/MSP430/MSP430InstrInfo.cpp index 5c3a3fc69266..46c6dd7a97d8 100644 --- a/llvm/lib/Target/MSP430/MSP430InstrInfo.cpp +++ b/llvm/lib/Target/MSP430/MSP430InstrInfo.cpp @@ -37,7 +37,8 @@ void MSP430InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned SrcReg, bool isKill, int FrameIdx, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const { + const TargetRegisterInfo *TRI, + unsigned flags) const { DebugLoc DL; if (MI != MBB.end()) DL = MI->getDebugLoc(); MachineFunction &MF = *MBB.getParent(); @@ -64,7 +65,8 @@ void MSP430InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, int FrameIdx, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const{ + const TargetRegisterInfo *TRI, + unsigned flags) const{ DebugLoc DL; if (MI != MBB.end()) DL = MI->getDebugLoc(); MachineFunction &MF = *MBB.getParent(); diff --git a/llvm/lib/Target/MSP430/MSP430InstrInfo.h b/llvm/lib/Target/MSP430/MSP430InstrInfo.h index 13c50ad23adc..62eb68e55f7d 100644 --- a/llvm/lib/Target/MSP430/MSP430InstrInfo.h +++ b/llvm/lib/Target/MSP430/MSP430InstrInfo.h @@ -44,12 +44,14 @@ class MSP430InstrInfo : public MSP430GenInstrInfo { unsigned 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 MI, unsigned DestReg, int FrameIdx, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const override; + const TargetRegisterInfo *TRI, + unsigned flags = 0) const override; unsigned getInstSizeInBytes(const MachineInstr &MI) const override; diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.h b/llvm/lib/Target/Mips/MipsInstrInfo.h index a626c0c3fdb8..d7ff28c03720 100644 --- a/llvm/lib/Target/Mips/MipsInstrInfo.h +++ b/llvm/lib/Target/Mips/MipsInstrInfo.h @@ -113,7 +113,8 @@ class MipsInstrInfo : public MipsGenInstrInfo { MachineBasicBlock::iterator MBBI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const override { + const TargetRegisterInfo *TRI, + unsigned flags = 0) const override { storeRegToStack(MBB, MBBI, SrcReg, isKill, FrameIndex, RC, TRI, 0); } @@ -121,7 +122,8 @@ class MipsInstrInfo : public MipsGenInstrInfo { MachineBasicBlock::iterator MBBI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const override { + const TargetRegisterInfo *TRI, + unsigned flags = 0) const override { loadRegFromStack(MBB, MBBI, DestReg, FrameIndex, RC, TRI, 0); } diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp index a03742d74025..3d9c7eda022c 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp @@ -1230,7 +1230,8 @@ void PPCInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, unsigned SrcReg, bool isKill, int FrameIdx, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const { + const TargetRegisterInfo *TRI, + unsigned flags) const { MachineFunction &MF = *MBB.getParent(); SmallVector NewMIs; @@ -1282,7 +1283,8 @@ PPCInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, int FrameIdx, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const { + const TargetRegisterInfo *TRI, + unsigned flags) const { MachineFunction &MF = *MBB.getParent(); SmallVector NewMIs; DebugLoc DL; diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.h b/llvm/lib/Target/PowerPC/PPCInstrInfo.h index 112b163c5c4d..dd8b51a9e882 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.h +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.h @@ -288,13 +288,15 @@ class PPCInstrInfo : public PPCGenInstrInfo { MachineBasicBlock::iterator MBBI, unsigned 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, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const override; + const TargetRegisterInfo *TRI, + unsigned flags = 0) const override; unsigned getStoreOpcodeForSpill(unsigned Reg, const TargetRegisterClass *RC = nullptr) const; diff --git a/llvm/lib/Target/RISCV/RISCV.h b/llvm/lib/Target/RISCV/RISCV.h index 834a1d171143..682ace8401c0 100644 --- a/llvm/lib/Target/RISCV/RISCV.h +++ b/llvm/lib/Target/RISCV/RISCV.h @@ -29,6 +29,9 @@ class PassRegistry; void LowerRISCVMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, const AsmPrinter &AP); +//SSITH +void LowerToSSITHEpilogStore(const MachineInstr *MI, MCInst &OutMI, + const AsmPrinter &AP); bool LowerRISCVMachineOperandToMCOperand(const MachineOperand &MO, MCOperand &MCOp, const AsmPrinter &AP); diff --git a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp index 5b4518dfd048..2d958a335c70 100644 --- a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp +++ b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp @@ -19,13 +19,27 @@ #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" +#include "llvm/MC/SSITHMetadata.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/raw_ostream.h" + +//SSITH Extra includes +#include "MCTargetDesc/RISCVFixupKinds.h" +#include "llvm/BinaryFormat/ELF.h" +#include "llvm/MC/MCAsmBackend.h" +#include "llvm/MC/MCFixupKindInfo.h" +#include "llvm/MC/MCFixup.h" +#include "llvm/MC/MCSectionELF.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/SSITHMetadata.h" +#include "llvm/Target/TargetLoweringObjectFile.h" + using namespace llvm; #define DEBUG_TYPE "asm-printer" @@ -46,10 +60,15 @@ class RISCVAsmPrinter : public AsmPrinter { bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS) override; - void EmitToStreamer(MCStreamer &S, const MCInst &Inst); + bool EmitToStreamer(MCStreamer &S, const MCInst &Inst); bool emitPseudoExpansionLowering(MCStreamer &OutStreamer, const MachineInstr *MI); + //SSITH Addition + void EmitSSITHMetadataInst(MCSymbol *Sym, const MCSubtargetInfo &STI, uint8_t tag) override; + void EmitSSITHMetadataFnRange(MCSymbol *begin, MCSymbol *end, + const MCSubtargetInfo &STI) override; + // Wrapper needed for tblgenned pseudo lowering. bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const { return LowerRISCVMachineOperandToMCOperand(MO, MCOp, *this); @@ -59,25 +78,196 @@ class RISCVAsmPrinter : public AsmPrinter { #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()); AsmPrinter::EmitToStreamer(*OutStreamer, Res ? CInst : Inst); + + return Res; } // Simple pseudo-instructions have their lowering (with expansion to real // instructions) auto-generated. #include "RISCVGenMCPseudoLowering.inc" +//SSITH +void RISCVAsmPrinter::EmitSSITHMetadataFnRange(MCSymbol *begin, MCSymbol *end, + const MCSubtargetInfo &STI){ + + SmallVector Fixups; + + //Make MCExpr for the fixups -- Inspired by LowerSymbolOperand in RISCVMCInstLower.cpp + MCContext &Ctx = OutContext; + RISCVMCExpr::VariantKind Kind = RISCVMCExpr::VK_RISCV_None; + const MCExpr *MEbegin = MCSymbolRefExpr::create(begin, MCSymbolRefExpr::VK_None, Ctx); + const MCExpr *MEend = MCSymbolRefExpr::create(end, MCSymbolRefExpr::VK_None, Ctx); + MEbegin = RISCVMCExpr::create(MEbegin, Kind, Ctx); + MEend = RISCVMCExpr::create(MEend, Kind, Ctx); + + //Push fixup -- 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))); + + OutStreamer->EmitSSITHMetadataEntry(Fixups, STI, DMD_FUNCTION_RANGE, 0); +} + +//SSITH +void RISCVAsmPrinter::EmitSSITHMetadataInst(MCSymbol *Sym, const MCSubtargetInfo &STI, + uint8_t tag){ + SmallVector Fixups; + + //Make MCExpr for the fixups -- Inspired by LowerSymbolOperand in RISCVMCInstLower.cpp + MCContext &Ctx = OutContext; + RISCVMCExpr::VariantKind Kind = RISCVMCExpr::VK_RISCV_None; + const MCExpr *ME = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Ctx); + ME = RISCVMCExpr::create(ME, Kind, Ctx); + + //Push fixup -- the linker will write the 4 byte address for us + Fixups.push_back( + MCFixup::create(0, ME, MCFixupKind(FK_Data_4), SMLoc::getFromPointer(nullptr))); + + OutStreamer->EmitSSITHMetadataEntry(Fixups, STI, DMD_TAG_ADDRESS_OP, tag); +} + void RISCVAsmPrinter::EmitInstruction(const MachineInstr *MI) { + /* SSITH BEGIN */ + MCSymbol *InstSym, *PriorInstSym; + InstSym = PriorInstSym = nullptr; + // Do any auto-generated pseudo lowerings. - if (emitPseudoExpansionLowering(*OutStreamer, MI)) - return; + if (!emitPseudoExpansionLowering(*OutStreamer, MI)){ + MCInst TmpInst; + LowerRISCVMachineInstrToMCInst(MI, TmpInst, *this); + EmitToStreamer(*OutStreamer, TmpInst); + } + + char *tmp = OutStreamer->SSITHpopLastInstruction(4); + InstSym = OutContext.createTempSymbol(); + OutStreamer->EmitLabel(InstSym); + //These get expanded to 2 instructions -- can you believe it! They aren't butter! + //they are whatever the fake butter product in those ads was called ... + if(MI->getOpcode() == RISCV::PseudoTAIL || + MI->getOpcode() == RISCV::PseudoCALL){ + char *tmp2 = OutStreamer->SSITHpopLastInstruction(4); + PriorInstSym = OutContext.createTempSymbol(); + OutStreamer->EmitLabel(PriorInstSym); + OutStreamer->SSITHpushInstruction(tmp2, 4); + } + OutStreamer->SSITHpushInstruction(tmp, 4); + + //Get the new section + MCContext &Context = getObjFileLowering().getContext(); + MCSectionELF *ISP = Context.getELFSection(".dover_metadata", ELF::SHT_PROGBITS, 0); + + bool retTarget = false; + bool branchFallThrough = false; + + const MachineBasicBlock *MBB = MI->getParent(); + if(MI == MBB->getFirstNonDebugInstr()){ + for(auto &pred : MBB->predecessors()){ + const auto &last = pred->getLastNonDebugInstr(); + if(last != pred->end()) { + if(last->isCall()) + retTarget = true; + if(last->isBranch()) + branchFallThrough = true; + } + } + } + else{ + for(auto &MI2 : *(MBB)){ + if(&MI2 == MI) + break; + + //The zero size instructions from RISCVInstrInfo.cpp - getInstSizeInBytes + //wasn't obvious how to call it, so here's this unmaintable approach + switch(MI2.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(MI2.isCall()) + retTarget = true; + else + retTarget = false; + + if(MI2.isBranch()) + branchFallThrough = true; + else + branchFallThrough = false; + } + } + + //Swith to new section for ssith metadata + OutStreamer->PushSection(); + OutStreamer->SwitchSection(ISP); + if(MI->getFlag(MachineInstr::FnProlog)) + EmitSSITHMetadataInst(InstSym, getSubtargetInfo(), DMT_STACK_PROLOGUE_AUTHORITY); + else if(MI->getFlag(MachineInstr::FnEpilog)){ + EmitSSITHMetadataInst(InstSym, getSubtargetInfo(), DMT_STACK_EPILOGUE_AUTHORITY); + } + else if(MI->getFlag(MachineInstr::FPtrStore)){ + //MI->dump(); + //errs() << "store\n--------------------\n"; + EmitSSITHMetadataInst(InstSym, getSubtargetInfo(), DMT_FPTR_STORE_AUTHORITY); + } + else if(MI->getFlag(MachineInstr::FPtrCreate)){ + //MI->dump(); + //errs() << "create\n--------------------\n"; + EmitSSITHMetadataInst(InstSym, getSubtargetInfo(), DMT_FPTR_CREATE_AUTHORITY); + } + //return instructions aren't tagged epilog for whatever reason + else if(MI->isReturn() && !MI->isCall()){ + //NOTE -- Tail Calls get labelled as both return and call, we consider them calls + EmitSSITHMetadataInst(InstSym, getSubtargetInfo(), DMT_STACK_EPILOGUE_AUTHORITY); + EmitSSITHMetadataInst(InstSym, getSubtargetInfo(), DMT_RETURN_INSTR); + } + //Tag call instructions for 3 class CFI policy + else if(MI->isCall()) + EmitSSITHMetadataInst(InstSym, getSubtargetInfo(), DMT_CALL_INSTR); + //Tag branch instruction for 3 class CFI policy + else if(MI->isBranch()) + EmitSSITHMetadataInst(InstSym, getSubtargetInfo(), DMT_BRANCH_INSTR); + + //whether its a tail call or a return (handled separately above) do this + if(MI->isReturn()) + EmitSSITHMetadataFnRange(CurrentFnSym, InstSym, getSubtargetInfo()); + + //Targets can also be other things, need a separate if check + if(retTarget){ + MCSymbol *Tgt = PriorInstSym ? PriorInstSym : InstSym; + EmitSSITHMetadataInst(Tgt, getSubtargetInfo(), DMT_RET_VALID_TGT); + } + else if(branchFallThrough){ + MCSymbol *Tgt = PriorInstSym ? PriorInstSym : InstSym; + EmitSSITHMetadataInst(Tgt, getSubtargetInfo(), DMT_BRANCH_VALID_TGT); + } + //Restore the previous section + OutStreamer->PopSection(); - MCInst TmpInst; - LowerRISCVMachineInstrToMCInst(MI, TmpInst, *this); - EmitToStreamer(*OutStreamer, TmpInst); + //SSITH - clean up in function epilog + if(MI->getFlag(MachineInstr::FnEpilog) && MI->getOpcode() == RISCV::LW){ + //Emit the metadata + MCSymbol *CurPos = OutContext.createTempSymbol(); + OutStreamer->EmitLabel(CurPos); + OutStreamer->PushSection(); + OutStreamer->SwitchSection(ISP); + EmitSSITHMetadataInst(CurPos, getSubtargetInfo(), DMT_STACK_EPILOGUE_AUTHORITY); + OutStreamer->PopSection(); + + //Emit our new store + MCInst SSITHStore; + LowerToSSITHEpilogStore(MI, SSITHStore, *this); + EmitToStreamer(*OutStreamer, SSITHStore); + } } bool RISCVAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp index 6e0703c7b021..66dd64ac06c7 100644 --- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp @@ -117,7 +117,8 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF, return; // 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)); // The frame pointer is callee-saved, and code has been generated for us to // save it to the stack. We need to skip over the storing of callee-saved @@ -131,7 +132,8 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF, // Generate new FP. if (hasFP(MF)) adjustReg(MBB, MBBI, DL, FPReg, SPReg, - StackSize - RVFI->getVarArgsSaveSize(), MachineInstr::FrameSetup); + StackSize - RVFI->getVarArgsSaveSize(), + (MachineInstr::MIFlag)(MachineInstr::FrameSetup | MachineInstr::FnProlog)); } void RISCVFrameLowering::emitEpilogue(MachineFunction &MF, @@ -158,11 +160,12 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF, assert(hasFP(MF) && "frame pointer should not have been eliminated"); adjustReg(MBB, LastFrameDestroy, DL, SPReg, FPReg, -StackSize + RVFI->getVarArgsSaveSize(), - MachineInstr::FrameDestroy); + (MachineInstr::MIFlag)(MachineInstr::FrameDestroy | MachineInstr::FnEpilog)); } // 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/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 377933e938c0..0838e71906dc 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -428,6 +428,7 @@ SDValue RISCVTargetLowering::lowerGlobalAddress(SDValue Op, SDLoc DL(Op); EVT Ty = Op.getValueType(); GlobalAddressSDNode *N = cast(Op); + const GlobalValue *GV = N->getGlobal(); int64_t Offset = N->getOffset(); MVT XLenVT = Subtarget.getXLenVT(); @@ -443,6 +444,13 @@ SDValue RISCVTargetLowering::lowerGlobalAddress(SDValue Op, if (Offset != 0) return DAG.getNode(ISD::ADD, DL, Ty, Addr, DAG.getConstant(Offset, DL, XLenVT)); + //SSITH + PointerType *ptr_t = dyn_cast(GV->getType()); + if(ptr_t && ptr_t->getElementType()->isFunctionTy()){ + SDNodeFlags Flags = Addr.getNode()->getFlags(); + Flags.setFPtrCreate(true); + Addr.getNode()->setFlags(Flags); + } return Addr; } diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp index 42fc5123003a..52a377a9e8a6 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp @@ -109,7 +109,8 @@ void RISCVInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned 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(); @@ -129,14 +130,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, unsigned 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(); @@ -153,7 +156,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::movImm32(MachineBasicBlock &MBB, diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.h b/llvm/lib/Target/RISCV/RISCVInstrInfo.h index ff098e660d19..de4c609ae9b0 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.h +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.h @@ -39,12 +39,14 @@ class RISCVInstrInfo : public RISCVGenInstrInfo { MachineBasicBlock::iterator MBBI, unsigned 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, unsigned DstReg, int FrameIndex, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const override; + const TargetRegisterInfo *TRI, + unsigned flags = 0) const override; // Materializes the given int32 Val into DstReg. void movImm32(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, diff --git a/llvm/lib/Target/RISCV/RISCVMCInstLower.cpp b/llvm/lib/Target/RISCV/RISCVMCInstLower.cpp index ba0cfd9edb61..e0faac8c3cc0 100644 --- a/llvm/lib/Target/RISCV/RISCVMCInstLower.cpp +++ b/llvm/lib/Target/RISCV/RISCVMCInstLower.cpp @@ -114,3 +114,19 @@ void llvm::LowerRISCVMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, OutMI.addOperand(MCOp); } } + +void llvm::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); + } +} diff --git a/llvm/lib/Target/Sparc/SparcInstrInfo.cpp b/llvm/lib/Target/Sparc/SparcInstrInfo.cpp index ad343fe6f80a..e85747770291 100644 --- a/llvm/lib/Target/Sparc/SparcInstrInfo.cpp +++ b/llvm/lib/Target/Sparc/SparcInstrInfo.cpp @@ -395,7 +395,8 @@ void SparcInstrInfo:: storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned 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(); @@ -434,7 +435,8 @@ void SparcInstrInfo:: loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned DestReg, int FI, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const { + const TargetRegisterInfo *TRI, + unsigned flags) const { DebugLoc DL; if (I != MBB.end()) DL = I->getDebugLoc(); diff --git a/llvm/lib/Target/Sparc/SparcInstrInfo.h b/llvm/lib/Target/Sparc/SparcInstrInfo.h index b587b28c25fc..e1f82a5047fc 100644 --- a/llvm/lib/Target/Sparc/SparcInstrInfo.h +++ b/llvm/lib/Target/Sparc/SparcInstrInfo.h @@ -88,13 +88,15 @@ class SparcInstrInfo : public SparcGenInstrInfo { MachineBasicBlock::iterator MBBI, unsigned 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, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const override; + const TargetRegisterInfo *TRI, + unsigned flags = 0) const override; unsigned getGlobalBaseReg(MachineFunction *MF) const; diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp index cb963a10010c..4fcaa89bfe2d 100644 --- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp +++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp @@ -883,7 +883,7 @@ void SystemZInstrInfo::copyPhysReg(MachineBasicBlock &MBB, void SystemZInstrInfo::storeRegToStackSlot( MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned SrcReg, bool isKill, int FrameIdx, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const { + const TargetRegisterInfo *TRI, unsigned flags) const { DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); // Callers may expect a single instruction, so keep 128-bit moves @@ -898,7 +898,7 @@ void SystemZInstrInfo::storeRegToStackSlot( void SystemZInstrInfo::loadRegFromStackSlot( MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, int FrameIdx, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const { + const TargetRegisterInfo *TRI, unsigned flags) const { DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); // Callers may expect a single instruction, so keep 128-bit moves diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.h b/llvm/lib/Target/SystemZ/SystemZInstrInfo.h index c5d1917b3292..99d2b53a8fc3 100644 --- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.h +++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.h @@ -235,12 +235,14 @@ class SystemZInstrInfo : public SystemZGenInstrInfo { MachineBasicBlock::iterator MBBI, unsigned 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, unsigned DestReg, int FrameIdx, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const override; + const TargetRegisterInfo *TRI, + unsigned flags = 0) const override; MachineInstr *convertToThreeAddress(MachineFunction::iterator &MFI, MachineInstr &MI, LiveVariables *LV) const override; diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp index 7b68cc2dc3ae..35115f7482d9 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.cpp +++ b/llvm/lib/Target/X86/X86InstrInfo.cpp @@ -3010,7 +3010,8 @@ void X86InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned SrcReg, bool isKill, int FrameIdx, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const { + const TargetRegisterInfo *TRI, + unsigned flag) const { const MachineFunction &MF = *MBB.getParent(); assert(MF.getFrameInfo().getObjectSize(FrameIdx) >= TRI->getSpillSize(*RC) && "Stack slot too small for store"); @@ -3046,7 +3047,8 @@ void X86InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, int FrameIdx, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const { + const TargetRegisterInfo *TRI, + unsigned flag) const { const MachineFunction &MF = *MBB.getParent(); unsigned Alignment = std::max(TRI->getSpillSize(*RC), 16); bool isAligned = diff --git a/llvm/lib/Target/X86/X86InstrInfo.h b/llvm/lib/Target/X86/X86InstrInfo.h index 49f76606e8df..7b7eece47aaf 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.h +++ b/llvm/lib/Target/X86/X86InstrInfo.h @@ -314,7 +314,8 @@ class X86InstrInfo final : public X86GenInstrInfo { MachineBasicBlock::iterator MI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const override; + const TargetRegisterInfo *TRI, + unsigned flags = 0) const override; void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, bool isKill, SmallVectorImpl &Addr, @@ -325,7 +326,8 @@ class X86InstrInfo final : public X86GenInstrInfo { void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const override; + const TargetRegisterInfo *TRI, + unsigned flags = 0) const override; void loadRegFromAddr(MachineFunction &MF, unsigned DestReg, SmallVectorImpl &Addr, diff --git a/llvm/lib/Target/XCore/XCoreInstrInfo.cpp b/llvm/lib/Target/XCore/XCoreInstrInfo.cpp index bbad8e354586..085b17b5281e 100644 --- a/llvm/lib/Target/XCore/XCoreInstrInfo.cpp +++ b/llvm/lib/Target/XCore/XCoreInstrInfo.cpp @@ -360,7 +360,8 @@ void XCoreInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const + const TargetRegisterInfo *TRI, + unsigned flag) const { DebugLoc DL; if (I != MBB.end() && !I->isDebugInstr()) @@ -382,7 +383,8 @@ void XCoreInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const + const TargetRegisterInfo *TRI, + unsigned flag) const { DebugLoc DL; if (I != MBB.end() && !I->isDebugInstr()) diff --git a/llvm/lib/Target/XCore/XCoreInstrInfo.h b/llvm/lib/Target/XCore/XCoreInstrInfo.h index b9621f136589..e74a14982227 100644 --- a/llvm/lib/Target/XCore/XCoreInstrInfo.h +++ b/llvm/lib/Target/XCore/XCoreInstrInfo.h @@ -70,13 +70,15 @@ class XCoreInstrInfo : public XCoreGenInstrInfo { MachineBasicBlock::iterator MI, unsigned 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 MI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const override; + const TargetRegisterInfo *TRI, + unsigned flags = 0) const override; bool reverseBranchCondition( SmallVectorImpl &Cond) const override; diff --git a/llvm/utils/TableGen/PseudoLoweringEmitter.cpp b/llvm/utils/TableGen/PseudoLoweringEmitter.cpp index 3a80d8e5d1c4..bac429084d47 100644 --- a/llvm/utils/TableGen/PseudoLoweringEmitter.cpp +++ b/llvm/utils/TableGen/PseudoLoweringEmitter.cpp @@ -200,7 +200,7 @@ void PseudoLoweringEmitter::emitLoweringEmitter(raw_ostream &o) { o << "bool " << Target.getName() + "AsmPrinter" << "::\n" << "emitPseudoExpansionLowering(MCStreamer &OutStreamer,\n" - << " const MachineInstr *MI) {\n"; + << " const MachineInstr *MI){\n"; if (!Expansions.empty()) { o << " switch (MI->getOpcode()) {\n"