mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-30 17:25:21 +00:00
Add a new attribute called 'jumptable' that creates jump-instruction tables for functions marked with this attribute.
It includes a pass that rewrites all indirect calls to jumptable functions to pass through these tables. This also adds backend support for generating the jump-instruction tables on ARM and X86. Note that since the jumptable attribute creates a second function pointer for a function, any function marked with jumptable must also be marked with unnamed_addr. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@210280 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -202,6 +202,21 @@ FunctionSections("function-sections",
|
||||
cl::desc("Emit functions into separate sections"),
|
||||
cl::init(false));
|
||||
|
||||
cl::opt<llvm::JumpTable::JumpTableType>
|
||||
JTableType("jump-table-type",
|
||||
cl::desc("Choose the type of Jump-Instruction Table for jumptable."),
|
||||
cl::init(JumpTable::Single),
|
||||
cl::values(
|
||||
clEnumValN(JumpTable::Single, "single",
|
||||
"Create a single table for all jumptable functions"),
|
||||
clEnumValN(JumpTable::Arity, "arity",
|
||||
"Create one table per number of parameters."),
|
||||
clEnumValN(JumpTable::Simplified, "simplified",
|
||||
"Create one table per simplified function type."),
|
||||
clEnumValN(JumpTable::Full, "full",
|
||||
"Create one table per unique function type."),
|
||||
clEnumValEnd));
|
||||
|
||||
// Common utility function tightly tied to the options listed here. Initializes
|
||||
// a TargetOptions object with CodeGen flags and returns it.
|
||||
static inline TargetOptions InitTargetOptionsFromCodeGenFlags() {
|
||||
@@ -228,6 +243,7 @@ static inline TargetOptions InitTargetOptionsFromCodeGenFlags() {
|
||||
Options.FunctionSections = FunctionSections;
|
||||
|
||||
Options.MCOptions = InitMCTargetOptionsFromFlags();
|
||||
Options.JTType = JTableType;
|
||||
|
||||
return Options;
|
||||
}
|
||||
|
102
include/llvm/CodeGen/JumpInstrTables.h
Normal file
102
include/llvm/CodeGen/JumpInstrTables.h
Normal file
@@ -0,0 +1,102 @@
|
||||
//===-- JumpInstrTables.h: Jump-Instruction Tables --------------*- C++ -*-===//
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// \brief An implementation of tables consisting of jump instructions
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CODEGEN_JUMPINSTRTABLES_H
|
||||
#define LLVM_CODEGEN_JUMPINSTRTABLES_H
|
||||
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
|
||||
namespace llvm {
|
||||
class Constant;
|
||||
class Function;
|
||||
class FunctionType;
|
||||
class JumpInstrTableInfo;
|
||||
class Module;
|
||||
|
||||
/// A class to manage a set of jump tables indexed on function type. It looks at
|
||||
/// each function in the module to find all the functions that have the
|
||||
/// jumptable attribute set. For each such function, it creates a new
|
||||
/// jump-instruction-table function and stores the mapping in the ImmutablePass
|
||||
/// JumpInstrTableInfo.
|
||||
///
|
||||
/// These special functions get lowered in AsmPrinter to assembly of the form:
|
||||
/// .globl f
|
||||
/// .type f,@function
|
||||
/// .align 8,0x90
|
||||
/// f:
|
||||
/// jmp f_orig@PLT
|
||||
///
|
||||
/// Support for an architecture depends on two functions in TargetInstrInfo:
|
||||
/// getUnconditionalBranch, and getTrap. AsmPrinter uses these to generate the
|
||||
/// appropriate instructions for the jump statement (an unconditional branch)
|
||||
/// and for padding to make the table have a size that is a power of two. This
|
||||
/// padding uses a trap instruction to ensure that calls to this area halt the
|
||||
/// program. The default implementations of these functions call
|
||||
/// llvm_unreachable.
|
||||
class JumpInstrTables : public ModulePass {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
JumpInstrTables();
|
||||
JumpInstrTables(JumpTable::JumpTableType JTT);
|
||||
virtual ~JumpInstrTables();
|
||||
bool runOnModule(Module &M) override;
|
||||
const char *getPassName() const override { return "Jump-Instruction Tables"; }
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override;
|
||||
|
||||
/// Creates a jump-instruction table function for the Target and adds it to
|
||||
/// the tables.
|
||||
Function *insertEntry(Module &M, Function *Target);
|
||||
|
||||
/// Checks to see if there is already a table for the given FunctionType.
|
||||
bool hasTable(FunctionType *FunTy);
|
||||
|
||||
private:
|
||||
/// The metadata used while a jump table is being built
|
||||
struct TableMeta {
|
||||
/// The number of this table
|
||||
unsigned TableNum;
|
||||
|
||||
/// The current number of jump entries in the table.
|
||||
unsigned Count;
|
||||
};
|
||||
|
||||
typedef DenseMap<FunctionType *, struct TableMeta> JumpMap;
|
||||
|
||||
/// Maps the function into a subset of function types, depending on the
|
||||
/// jump-instruction table style selected from JumpTableTypes in
|
||||
/// JumpInstrTables.cpp. The choice of mapping determines the number of
|
||||
/// jump-instruction tables generated by this pass. E.g., the simplest mapping
|
||||
/// converts every function type into void f(); so, all functions end up in a
|
||||
/// single table.
|
||||
FunctionType *transformType(FunctionType *FunTy);
|
||||
|
||||
/// The current state of functions and jump entries in the table(s).
|
||||
JumpMap Metadata;
|
||||
|
||||
/// The ImmutablePass that stores information about the generated tables.
|
||||
JumpInstrTableInfo *JITI;
|
||||
|
||||
/// The total number of tables.
|
||||
unsigned TableCount;
|
||||
|
||||
/// The type of tables to build.
|
||||
JumpTable::JumpTableType JTType;
|
||||
};
|
||||
|
||||
/// Creates a JumpInstrTables pass for the given type of jump table.
|
||||
ModulePass *createJumpInstrTablesPass(JumpTable::JumpTableType JTT);
|
||||
}
|
||||
|
||||
#endif /* LLVM_CODEGEN_JUMPINSTRTABLES_H */
|
@@ -588,6 +588,8 @@ namespace llvm {
|
||||
/// the intrinsic for later emission to the StackMap.
|
||||
extern char &StackMapLivenessID;
|
||||
|
||||
/// createJumpInstrTables - This pass creates jump-instruction tables.
|
||||
ModulePass *createJumpInstrTablesPass();
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user