X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FX86%2FX86AsmPrinter.h;h=7f5d127c68d5c6f077a1c903f332bc9d3f31e93d;hb=295b19789ddd4e1e0960beaf1a312dc1fab8e08e;hp=6db9e45dc3b2acca4b0959c229f5a657f279b278;hpb=25ab690a43cbbb591b76d49e3595b019c32f4b3f;p=oota-llvm.git diff --git a/lib/Target/X86/X86AsmPrinter.h b/lib/Target/X86/X86AsmPrinter.h old mode 100755 new mode 100644 index 6db9e45dc3b..7f5d127c68d --- a/lib/Target/X86/X86AsmPrinter.h +++ b/lib/Target/X86/X86AsmPrinter.h @@ -1,84 +1,131 @@ -//===-- X86AsmPrinter.h - Convert X86 LLVM code to Intel assembly ---------===// +//===-- X86AsmPrinter.h - X86 implementation of AsmPrinter ------*- C++ -*-===// // // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file the shared super class printer that converts from our internal -// representation of machine-dependent LLVM code to Intel and AT&T format -// assembly language. This printer is the output mechanism used by `llc'. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef X86ASMPRINTER_H -#define X86ASMPRINTER_H +#ifndef LLVM_LIB_TARGET_X86_X86ASMPRINTER_H +#define LLVM_LIB_TARGET_X86_X86ASMPRINTER_H -#include "X86.h" -#include "X86TargetMachine.h" +#include "X86Subtarget.h" #include "llvm/CodeGen/AsmPrinter.h" -#include "llvm/CodeGen/DwarfWriter.h" -#include "llvm/CodeGen/MachineDebugInfo.h" -#include "llvm/ADT/Statistic.h" -#include +#include "llvm/CodeGen/FaultMaps.h" +#include "llvm/CodeGen/StackMaps.h" +#include "llvm/Target/TargetMachine.h" +// Implemented in X86MCInstLower.cpp +namespace { + class X86MCInstLower; +} namespace llvm { +class MCStreamer; +class MCSymbol; -extern Statistic<> EmittedInsts; +class LLVM_LIBRARY_VISIBILITY X86AsmPrinter : public AsmPrinter { + const X86Subtarget *Subtarget; + StackMaps SM; + FaultMaps FM; + + // This utility class tracks the length of a stackmap instruction's 'shadow'. + // It is used by the X86AsmPrinter to ensure that the stackmap shadow + // invariants (i.e. no other stackmaps, patchpoints, or control flow within + // the shadow) are met, while outputting a minimal number of NOPs for padding. + // + // To minimise the number of NOPs used, the shadow tracker counts the number + // of instruction bytes output since the last stackmap. Only if there are too + // few instruction bytes to cover the shadow are NOPs used for padding. + class StackMapShadowTracker { + public: + StackMapShadowTracker(TargetMachine &TM); + ~StackMapShadowTracker(); + void startFunction(MachineFunction &MF); + void count(MCInst &Inst, const MCSubtargetInfo &STI); + + // Called to signal the start of a shadow of RequiredSize bytes. + void reset(unsigned RequiredSize) { + RequiredShadowSize = RequiredSize; + CurrentShadowSize = 0; + InShadow = true; + } -// FIXME: Move this to CodeGen/AsmPrinter.h -namespace PICStyle { - enum X86AsmPICStyle { - Stub, GOT + // Called before every stackmap/patchpoint, and at the end of basic blocks, + // to emit any necessary padding-NOPs. + void emitShadowPadding(MCStreamer &OutStreamer, const MCSubtargetInfo &STI); + private: + TargetMachine &TM; + const MachineFunction *MF; + std::unique_ptr CodeEmitter; + bool InShadow; + + // RequiredShadowSize holds the length of the shadow specified in the most + // recently encountered STACKMAP instruction. + // CurrentShadowSize counts the number of bytes encoded since the most + // recently encountered STACKMAP, stopping when that number is greater than + // or equal to RequiredShadowSize. + unsigned RequiredShadowSize, CurrentShadowSize; }; -} -struct VISIBILITY_HIDDEN X86SharedAsmPrinter : public AsmPrinter { - DwarfWriter DW; + StackMapShadowTracker SMShadowTracker; - X86SharedAsmPrinter(std::ostream &O, X86TargetMachine &TM, - const TargetAsmInfo *T) - : AsmPrinter(O, TM, T), DW(O, this, T), X86PICStyle(PICStyle::GOT) { - Subtarget = &TM.getSubtarget(); - } + // All instructions emitted by the X86AsmPrinter should use this helper + // method. + // + // This helper function invokes the SMShadowTracker on each instruction before + // outputting it to the OutStream. This allows the shadow tracker to minimise + // the number of NOPs used for stackmap padding. + void EmitAndCountInstruction(MCInst &Inst); - bool doInitialization(Module &M); - bool doFinalization(Module &M); + void InsertStackMapShadows(MachineFunction &MF); + void LowerSTACKMAP(const MachineInstr &MI); + void LowerPATCHPOINT(const MachineInstr &MI, X86MCInstLower &MCIL); + void LowerSTATEPOINT(const MachineInstr &MI, X86MCInstLower &MCIL); + void LowerFAULTING_LOAD_OP(const MachineInstr &MI, X86MCInstLower &MCIL); - void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - if (Subtarget->isTargetDarwin()) { - AU.addRequired(); - } - MachineFunctionPass::getAnalysisUsage(AU); + void LowerTlsAddr(X86MCInstLower &MCInstLowering, const MachineInstr &MI); + + public: + explicit X86AsmPrinter(TargetMachine &TM, + std::unique_ptr Streamer) + : AsmPrinter(TM, std::move(Streamer)), SM(*this), FM(*this), + SMShadowTracker(TM) {} + + const char *getPassName() const override { + return "X86 Assembly / Object Emitter"; } - PICStyle::X86AsmPICStyle X86PICStyle; - - const X86Subtarget *Subtarget; + const X86Subtarget &getSubtarget() const { return *Subtarget; } + + void EmitStartOfAsmFile(Module &M) override; - // Necessary for Darwin to print out the apprioriate types of linker stubs - std::set FnStubs, GVStubs, LinkOnceStubs; + void EmitEndOfAsmFile(Module &M) override; - inline static bool isScale(const MachineOperand &MO) { - return MO.isImmediate() && - (MO.getImmedValue() == 1 || MO.getImmedValue() == 2 || - MO.getImmedValue() == 4 || MO.getImmedValue() == 8); + void EmitInstruction(const MachineInstr *MI) override; + + void EmitBasicBlockEnd(const MachineBasicBlock &MBB) override { + SMShadowTracker.emitShadowPadding(*OutStreamer, getSubtargetInfo()); } - inline static bool isMem(const MachineInstr *MI, unsigned Op) { - if (MI->getOperand(Op).isFrameIndex()) return true; - return Op+4 <= MI->getNumOperands() && - MI->getOperand(Op ).isRegister() && isScale(MI->getOperand(Op+1)) && - MI->getOperand(Op+2).isRegister() && - (MI->getOperand(Op+3).isImmediate() || - MI->getOperand(Op+3).isGlobalAddress() || - MI->getOperand(Op+3).isConstantPoolIndex() || - MI->getOperand(Op+3).isJumpTableIndex()); + bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, + unsigned AsmVariant, const char *ExtraCode, + raw_ostream &OS) override; + bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, + unsigned AsmVariant, const char *ExtraCode, + raw_ostream &OS) override; + + /// \brief Return the symbol for the specified constant pool entry. + MCSymbol *GetCPISymbol(unsigned CPID) const override; + + bool doInitialization(Module &M) override { + SMShadowTracker.reset(0); + SM.reset(); + return AsmPrinter::doInitialization(M); } + + bool runOnMachineFunction(MachineFunction &F) override; }; } // end namespace llvm