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"