mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-11-29 13:18:23 +00:00
[CodeGen] Introduce a FAULTING_LOAD_OP pseudo-op.
Summary: This instruction encodes a loading operation that may fault, and a label to branch to if the load page-faults. The locations of potentially faulting loads and their "handler" destinations are recorded in a FaultMap section, meant to be consumed by LLVM's clients. Nothing generates FAULTING_LOAD_OP instructions yet, but they will be used in a future change. The documentation (FaultMaps.rst) needs improvement and I will update this diff with a more expanded version shortly. Depends on D10196 Reviewers: rnk, reames, AndyAyers, ab, atrick, pgavlin Reviewed By: atrick, pgavlin Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D10197 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239740 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
73
include/llvm/CodeGen/FaultMaps.h
Normal file
73
include/llvm/CodeGen/FaultMaps.h
Normal file
@@ -0,0 +1,73 @@
|
||||
//===------------------- FaultMaps.h - StackMaps ----------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CODEGEN_FAULTMAPS_H
|
||||
#define LLVM_CODEGEN_FAULTMAPS_H
|
||||
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/MC/MCSymbol.h"
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class AsmPrinter;
|
||||
class MCExpr;
|
||||
class MCSymbol;
|
||||
class MCStreamer;
|
||||
|
||||
class FaultMaps {
|
||||
public:
|
||||
enum FaultType { FaultingLoad = 1, FaultTypeMax };
|
||||
|
||||
static const char *faultTypeToString(FaultType);
|
||||
|
||||
explicit FaultMaps(AsmPrinter &AP);
|
||||
|
||||
void recordFaultingOp(FaultType FaultTy, const MCSymbol *HandlerLabel);
|
||||
void serializeToFaultMapSection();
|
||||
|
||||
private:
|
||||
static const char *WFMP;
|
||||
|
||||
struct FaultInfo {
|
||||
FaultType FaultType;
|
||||
const MCExpr *FaultingOffsetExpr;
|
||||
const MCExpr *HandlerOffsetExpr;
|
||||
|
||||
FaultInfo()
|
||||
: FaultType(FaultTypeMax), FaultingOffsetExpr(nullptr),
|
||||
HandlerOffsetExpr(nullptr) {}
|
||||
|
||||
explicit FaultInfo(FaultMaps::FaultType FType, const MCExpr *FaultingOffset,
|
||||
const MCExpr *HandlerOffset)
|
||||
: FaultType(FType), FaultingOffsetExpr(FaultingOffset),
|
||||
HandlerOffsetExpr(HandlerOffset) {}
|
||||
};
|
||||
|
||||
typedef std::vector<FaultInfo> FunctionFaultInfos;
|
||||
|
||||
// We'd like to keep a stable iteration order for FunctionInfos to help
|
||||
// FileCheck based testing.
|
||||
struct MCSymbolComparator {
|
||||
bool operator()(const MCSymbol *LHS, const MCSymbol *RHS) const {
|
||||
return LHS->getName() < RHS->getName();
|
||||
}
|
||||
};
|
||||
|
||||
std::map<const MCSymbol *, FunctionFaultInfos, MCSymbolComparator>
|
||||
FunctionInfos;
|
||||
AsmPrinter &AP;
|
||||
|
||||
void emitFunctionInfo(const MCSymbol *FnLabel, const FunctionFaultInfos &FFI);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -139,6 +139,9 @@ protected:
|
||||
/// StackMap section.
|
||||
MCSection *StackMapSection;
|
||||
|
||||
/// FaultMap section.
|
||||
MCSection *FaultMapSection;
|
||||
|
||||
/// EH frame section.
|
||||
///
|
||||
/// It is initialized on demand so it can be overwritten (with uniquing).
|
||||
@@ -262,6 +265,7 @@ public:
|
||||
MCSection *getTLSBSSSection() const { return TLSBSSSection; }
|
||||
|
||||
MCSection *getStackMapSection() const { return StackMapSection; }
|
||||
MCSection *getFaultMapSection() const { return FaultMapSection; }
|
||||
|
||||
// ELF specific sections.
|
||||
MCSection *getDataRelSection() const { return DataRelSection; }
|
||||
|
||||
@@ -881,6 +881,12 @@ def FRAME_ALLOC : Instruction {
|
||||
let hasSideEffects = 0;
|
||||
let hasCtrlDep = 1;
|
||||
}
|
||||
def FAULTING_LOAD_OP : Instruction {
|
||||
let OutOperandList = (outs unknown:$dst);
|
||||
let InOperandList = (ins variable_ops);
|
||||
let usesCustomInserter = 1;
|
||||
let mayLoad = 1;
|
||||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@@ -122,6 +122,12 @@ enum {
|
||||
/// label. Created by the llvm.frameallocate intrinsic. It has two arguments:
|
||||
/// the symbol for the label and the frame index of the stack allocation.
|
||||
FRAME_ALLOC = 21,
|
||||
|
||||
/// Loading instruction that may page fault, bundled with associated
|
||||
/// information on how to handle such a page fault. It is intended to support
|
||||
/// "zero cost" null checks in managed languages by allowing LLVM to fold
|
||||
/// comparisions into existing memory operations.
|
||||
FAULTING_LOAD_OP = 22,
|
||||
};
|
||||
} // end namespace TargetOpcode
|
||||
} // end namespace llvm
|
||||
|
||||
Reference in New Issue
Block a user