LCOV - code coverage report
Current view: top level - lib/CodeGen - PatchableFunction.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 15 15 100.0 %
Date: 2018-10-20 13:21:21 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===-- PatchableFunction.cpp - Patchable prologues for LLVM -------------===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : // This file implements edits function bodies in place to support the
      11             : // "patchable-function" attribute.
      12             : //
      13             : //===----------------------------------------------------------------------===//
      14             : 
      15             : #include "llvm/CodeGen/MachineFunction.h"
      16             : #include "llvm/CodeGen/MachineFunctionPass.h"
      17             : #include "llvm/CodeGen/MachineInstrBuilder.h"
      18             : #include "llvm/CodeGen/Passes.h"
      19             : #include "llvm/CodeGen/TargetFrameLowering.h"
      20             : #include "llvm/CodeGen/TargetInstrInfo.h"
      21             : #include "llvm/CodeGen/TargetSubtargetInfo.h"
      22             : 
      23             : using namespace llvm;
      24             : 
      25             : namespace {
      26             : struct PatchableFunction : public MachineFunctionPass {
      27             :   static char ID; // Pass identification, replacement for typeid
      28       24656 :   PatchableFunction() : MachineFunctionPass(ID) {
      29       24656 :     initializePatchableFunctionPass(*PassRegistry::getPassRegistry());
      30       24656 :   }
      31             : 
      32             :   bool runOnMachineFunction(MachineFunction &F) override;
      33       24489 :    MachineFunctionProperties getRequiredProperties() const override {
      34       24489 :     return MachineFunctionProperties().set(
      35       24489 :         MachineFunctionProperties::Property::NoVRegs);
      36             :   }
      37             : };
      38             : }
      39             : 
      40             : /// Returns true if instruction \p MI will not result in actual machine code
      41             : /// instructions.
      42             : static bool doesNotGeneratecode(const MachineInstr &MI) {
      43             :   // TODO: Introduce an MCInstrDesc flag for this
      44          12 :   switch (MI.getOpcode()) {
      45             :   default: return false;
      46             :   case TargetOpcode::IMPLICIT_DEF:
      47             :   case TargetOpcode::KILL:
      48             :   case TargetOpcode::CFI_INSTRUCTION:
      49             :   case TargetOpcode::EH_LABEL:
      50             :   case TargetOpcode::GC_LABEL:
      51             :   case TargetOpcode::DBG_VALUE:
      52             :   case TargetOpcode::DBG_LABEL:
      53             :     return true;
      54             :   }
      55             : }
      56             : 
      57      379341 : bool PatchableFunction::runOnMachineFunction(MachineFunction &MF) {
      58      379341 :   if (!MF.getFunction().hasFnAttribute("patchable-function"))
      59             :     return false;
      60             : 
      61             : #ifndef NDEBUG
      62             :   Attribute PatchAttr = MF.getFunction().getFnAttribute("patchable-function");
      63             :   StringRef PatchType = PatchAttr.getValueAsString();
      64             :   assert(PatchType == "prologue-short-redirect" && "Only possibility today!");
      65             : #endif
      66             : 
      67             :   auto &FirstMBB = *MF.begin();
      68             :   MachineBasicBlock::iterator FirstActualI = FirstMBB.begin();
      69             :   for (; doesNotGeneratecode(*FirstActualI); ++FirstActualI)
      70             :     assert(FirstActualI != FirstMBB.end());
      71             : 
      72          10 :   auto *TII = MF.getSubtarget().getInstrInfo();
      73             :   auto MIB = BuildMI(FirstMBB, FirstActualI, FirstActualI->getDebugLoc(),
      74          20 :                      TII->get(TargetOpcode::PATCHABLE_OP))
      75             :                  .addImm(2)
      76          20 :                  .addImm(FirstActualI->getOpcode());
      77             : 
      78          38 :   for (auto &MO : FirstActualI->operands())
      79             :     MIB.add(MO);
      80             : 
      81          10 :   FirstActualI->eraseFromParent();
      82             :   MF.ensureAlignment(4);
      83             :   return true;
      84             : }
      85             : 
      86             : char PatchableFunction::ID = 0;
      87             : char &llvm::PatchableFunctionID = PatchableFunction::ID;
      88      109803 : INITIALIZE_PASS(PatchableFunction, "patchable-function",
      89             :                 "Implement the 'patchable-function' attribute", false, false)

Generated by: LCOV version 1.13