// TODO: Replace with a portable PRNG from C++11.
class PRNG {
public:
- PRNG(uint32_t Seed = 1) : State(Seed) {}
+ explicit PRNG(uint32_t Seed = 1) : State(Seed) {}
uint32_t operator()() {
// Lewis, Goodman, and Miller (1969)
///
/// \file
/// \brief This file implements a class to represent 64 bit integer constant
-/// values, and thier conversion to variable bit sized integers.
+/// values, and their conversion to variable bit sized integers.
///
/// Note: This is a simplified version of llvm/include/llvm/ADT/APInt.h for use
/// with Subzero.
namespace Ice {
class APInt {
+ APInt() = delete;
+ APInt(const APInt &) = delete;
+ APInt &operator=(const APInt &) = delete;
+
public:
/// Bits in an (internal) value.
static const SizeT APINT_BITS_PER_WORD = sizeof(uint64_t) * CHAR_BIT;
namespace Ice {
class Cfg {
+ Cfg() = delete;
Cfg(const Cfg &) = delete;
Cfg &operator=(const Cfg &) = delete;
namespace Ice {
class CfgNode {
+ CfgNode() = delete;
CfgNode(const CfgNode &) = delete;
CfgNode &operator=(const CfgNode &) = delete;
namespace Ice {
class CondX86 {
+ CondX86() = delete;
+ CondX86(const CondX86 &) = delete;
+ CondX86 &operator=(const CondX86 &) = delete;
+
public:
// An enum of condition codes used for branches and cmov. The enum value
// should match the value used to encode operands in binary instructions.
// respect to Translator. In particular, the unique_ptr ownership
// rules in LLVM2ICEFunctionConverter.
class LLVM2ICEConverter {
+ LLVM2ICEConverter() = delete;
LLVM2ICEConverter(const LLVM2ICEConverter &) = delete;
LLVM2ICEConverter &operator=(const LLVM2ICEConverter &) = delete;
public:
- LLVM2ICEConverter(Ice::Converter &Converter)
+ explicit LLVM2ICEConverter(Ice::Converter &Converter)
: Converter(Converter), Ctx(Converter.getContext()),
TypeConverter(Converter.getModule()->getContext()) {}
// Note: this currently assumes that the given IR was verified to be
// valid PNaCl bitcode. Otherwise, the behavior is undefined.
class LLVM2ICEFunctionConverter : LLVM2ICEConverter {
+ LLVM2ICEFunctionConverter() = delete;
LLVM2ICEFunctionConverter(const LLVM2ICEFunctionConverter &) = delete;
LLVM2ICEFunctionConverter &
operator=(const LLVM2ICEFunctionConverter &) = delete;
public:
- LLVM2ICEFunctionConverter(Ice::Converter &Converter)
+ explicit LLVM2ICEFunctionConverter(Ice::Converter &Converter)
: LLVM2ICEConverter(Converter), Func(nullptr) {}
void convertFunction(const Function *F) {
// Note: this currently assumes that the given IR was verified to be
// valid PNaCl bitcode. Othewise, the behavior is undefined.
class LLVM2ICEGlobalsConverter : public LLVM2ICEConverter {
+ LLVM2ICEGlobalsConverter() = delete;
LLVM2ICEGlobalsConverter(const LLVM2ICEGlobalsConverter &) = delete;
LLVM2ICEGlobalsConverter &
operator-(const LLVM2ICEGlobalsConverter &) = delete;
public:
- LLVM2ICEGlobalsConverter(Ice::Converter &Converter)
+ explicit LLVM2ICEGlobalsConverter(Ice::Converter &Converter)
: LLVM2ICEConverter(Converter) {}
/// Converts global variables, and their initializers into ICE
namespace Ice {
class Converter : public Translator {
+ Converter() = delete;
Converter(const Converter &) = delete;
Converter &operator=(const Converter &) = delete;
// file. Having both -fdata-sections and -ffunction-sections does allow
// relaxing this requirement.
class ELFObjectWriter {
+ ELFObjectWriter() = delete;
ELFObjectWriter(const ELFObjectWriter &) = delete;
ELFObjectWriter &operator=(const ELFObjectWriter &) = delete;
// Base representation of an ELF section.
class ELFSection {
+ ELFSection() = delete;
ELFSection(const ELFSection &) = delete;
ELFSection &operator=(const ELFSection &) = delete;
// Models text/code sections. Code is written out incrementally and the
// size of the section is then updated incrementally.
class ELFTextSection : public ELFSection {
+ ELFTextSection() = delete;
ELFTextSection(const ELFTextSection &) = delete;
ELFTextSection &operator=(const ELFTextSection &) = delete;
// size of the section is then updated incrementally.
// Some rodata sections may have fixed entsize and duplicates may be mergeable.
class ELFDataSection : public ELFSection {
+ ELFDataSection() = delete;
ELFDataSection(const ELFDataSection &) = delete;
ELFDataSection &operator=(const ELFDataSection &) = delete;
// Models a symbol table. Symbols may be added up until updateIndices is
// called. At that point the indices of each symbol will be finalized.
class ELFSymbolTableSection : public ELFSection {
+ ELFSymbolTableSection() = delete;
+ ELFSymbolTableSection(const ELFSymbolTableSection &) = delete;
+ ELFSymbolTableSection &operator=(const ELFSymbolTableSection &) = delete;
+
public:
using ELFSection::ELFSection;
// Models a relocation section.
class ELFRelocationSection : public ELFSection {
+ ELFRelocationSection() = delete;
ELFRelocationSection(const ELFRelocationSection &) = delete;
ELFRelocationSection &operator=(const ELFRelocationSection &) = delete;
// can be discovered and used to fill out section headers and symbol
// table entries.
class ELFStringTableSection : public ELFSection {
+ ELFStringTableSection() = delete;
ELFStringTableSection(const ELFStringTableSection &) = delete;
ELFStringTableSection &operator=(const ELFStringTableSection &) = delete;
// Low level writer that can that can handle ELFCLASS32/64.
// Little endian only for now.
class ELFStreamer {
+ ELFStreamer() = delete;
+ ELFStreamer(const ELFStreamer &) = delete;
+ ELFStreamer &operator=(const ELFStreamer &) = delete;
+
public:
explicit ELFStreamer(Fdstream &Out) : Out(Out) {}
// Assembler fixups are positions in generated code/data that hold relocation
// information that needs to be processed before finalizing the code/data.
struct AssemblerFixup {
+ AssemblerFixup &operator=(const AssemblerFixup &) = delete;
+
public:
+ AssemblerFixup() : position_(0), kind_(0), value_(nullptr) {}
+ AssemblerFixup(const AssemblerFixup &) = default;
intptr_t position() const { return position_; }
void set_position(intptr_t Position) { position_ = Position; }
};
class GlobalContext {
+ GlobalContext() = delete;
GlobalContext(const GlobalContext &) = delete;
GlobalContext &operator=(const GlobalContext &) = delete;
// TimerList is a vector of TimerStack objects, with extra methods
// to initialize and merge these vectors.
class TimerList : public std::vector<TimerStack> {
+ TimerList(const TimerList &) = delete;
+ TimerList &operator=(const TimerList &) = delete;
+
public:
+ TimerList() = default;
// initInto() initializes a target list of timers based on the
// current list. In particular, it creates the same number of
// timers, in the same order, with the same names, but initially
// pushes a marker, and the destructor pops it. This is for
// convenient timing of regions of code.
class TimerMarker {
+ TimerMarker() = delete;
TimerMarker(const TimerMarker &) = delete;
TimerMarker &operator=(const TimerMarker &) = delete;
/// Base class for global variable and function declarations.
class GlobalDeclaration {
+ GlobalDeclaration() = delete;
GlobalDeclaration(const GlobalDeclaration &) = delete;
GlobalDeclaration &operator=(const GlobalDeclaration &) = delete;
// Models a function declaration. This includes the type signature of
// the function, its calling conventions, and its linkage.
class FunctionDeclaration : public GlobalDeclaration {
+ FunctionDeclaration() = delete;
FunctionDeclaration(const FunctionDeclaration &) = delete;
FunctionDeclaration &operator=(const FunctionDeclaration &) = delete;
// from InstHighLevel, and low-level (target-specific) ICE
// instructions inherit from InstTarget.
class Inst : public llvm::ilist_node<Inst> {
+ Inst() = delete;
Inst(const Inst &) = delete;
Inst &operator=(const Inst &) = delete;
Unreachable,
Alloca,
Arithmetic,
- Assign, // not part of LLVM/PNaCl bitcode
Br,
Call,
Cast,
Select,
Store,
Switch,
+ Assign, // not part of LLVM/PNaCl bitcode
BundleLock, // not part of LLVM/PNaCl bitcode
BundleUnlock, // not part of LLVM/PNaCl bitcode
FakeDef, // not part of LLVM/PNaCl bitcode
};
class InstHighLevel : public Inst {
+ InstHighLevel() = delete;
InstHighLevel(const InstHighLevel &) = delete;
InstHighLevel &operator=(const InstHighLevel &) = delete;
// and the required alignment in bytes. The alignment must be either
// 0 (no alignment required) or a power of 2.
class InstAlloca : public InstHighLevel {
+ InstAlloca() = delete;
InstAlloca(const InstAlloca &) = delete;
InstAlloca &operator=(const InstAlloca &) = delete;
// Binary arithmetic instruction. The source operands are captured in
// getSrc(0) and getSrc(1).
class InstArithmetic : public InstHighLevel {
+ InstArithmetic() = delete;
InstArithmetic(const InstArithmetic &) = delete;
InstArithmetic &operator=(const InstArithmetic &) = delete;
// Inttoptr instruction, or as an intermediate step for lowering a
// Load instruction.
class InstAssign : public InstHighLevel {
+ InstAssign() = delete;
InstAssign(const InstAssign &) = delete;
InstAssign &operator=(const InstAssign &) = delete;
// Branch instruction. This represents both conditional and
// unconditional branches.
class InstBr : public InstHighLevel {
+ InstBr() = delete;
InstBr(const InstBr &) = delete;
InstBr &operator=(const InstBr &) = delete;
// Call instruction. The call target is captured as getSrc(0), and
// arg I is captured as getSrc(I+1).
class InstCall : public InstHighLevel {
+ InstCall() = delete;
InstCall(const InstCall &) = delete;
InstCall &operator=(const InstCall &) = delete;
// Cast instruction (a.k.a. conversion operation).
class InstCast : public InstHighLevel {
+ InstCast() = delete;
InstCast(const InstCast &) = delete;
InstCast &operator=(const InstCast &) = delete;
// ExtractElement instruction.
class InstExtractElement : public InstHighLevel {
+ InstExtractElement() = delete;
InstExtractElement(const InstExtractElement &) = delete;
InstExtractElement &operator=(const InstExtractElement &) = delete;
// Floating-point comparison instruction. The source operands are
// captured in getSrc(0) and getSrc(1).
class InstFcmp : public InstHighLevel {
+ InstFcmp() = delete;
InstFcmp(const InstFcmp &) = delete;
InstFcmp &operator=(const InstFcmp &) = delete;
// Integer comparison instruction. The source operands are captured
// in getSrc(0) and getSrc(1).
class InstIcmp : public InstHighLevel {
+ InstIcmp() = delete;
InstIcmp(const InstIcmp &) = delete;
InstIcmp &operator=(const InstIcmp &) = delete;
// InsertElement instruction.
class InstInsertElement : public InstHighLevel {
+ InstInsertElement() = delete;
InstInsertElement(const InstInsertElement &) = delete;
InstInsertElement &operator=(const InstInsertElement &) = delete;
// Call to an intrinsic function. The call target is captured as getSrc(0),
// and arg I is captured as getSrc(I+1).
class InstIntrinsicCall : public InstCall {
+ InstIntrinsicCall() = delete;
InstIntrinsicCall(const InstIntrinsicCall &) = delete;
InstIntrinsicCall &operator=(const InstIntrinsicCall &) = delete;
// Load instruction. The source address is captured in getSrc(0).
class InstLoad : public InstHighLevel {
+ InstLoad() = delete;
InstLoad(const InstLoad &) = delete;
InstLoad &operator=(const InstLoad &) = delete;
// Phi instruction. For incoming edge I, the node is Labels[I] and
// the Phi source operand is getSrc(I).
class InstPhi : public InstHighLevel {
+ InstPhi() = delete;
InstPhi(const InstPhi &) = delete;
InstPhi &operator=(const InstPhi &) = delete;
// there is no return value (void-type function), then
// getSrcSize()==0 and hasRetValue()==false.
class InstRet : public InstHighLevel {
+ InstRet() = delete;
InstRet(const InstRet &) = delete;
InstRet &operator=(const InstRet &) = delete;
// Select instruction. The condition, true, and false operands are captured.
class InstSelect : public InstHighLevel {
+ InstSelect() = delete;
InstSelect(const InstSelect &) = delete;
InstSelect &operator=(const InstSelect &) = delete;
// Store instruction. The address operand is captured, along with the
// data operand to be stored into the address.
class InstStore : public InstHighLevel {
+ InstStore() = delete;
InstStore(const InstStore &) = delete;
InstStore &operator=(const InstStore &) = delete;
// Switch instruction. The single source operand is captured as
// getSrc(0).
class InstSwitch : public InstHighLevel {
+ InstSwitch() = delete;
InstSwitch(const InstSwitch &) = delete;
InstSwitch &operator=(const InstSwitch &) = delete;
// Unreachable instruction. This is a terminator instruction with no
// operands.
class InstUnreachable : public InstHighLevel {
+ InstUnreachable() = delete;
InstUnreachable(const InstUnreachable &) = delete;
InstUnreachable &operator=(const InstUnreachable &) = delete;
}
private:
- InstUnreachable(Cfg *Func);
+ explicit InstUnreachable(Cfg *Func);
~InstUnreachable() override {}
};
// BundleLock instruction. There are no operands. Contains an option
// indicating whether align_to_end is specified.
class InstBundleLock : public InstHighLevel {
+ InstBundleLock() = delete;
InstBundleLock(const InstBundleLock &) = delete;
InstBundleLock &operator=(const InstBundleLock &) = delete;
// BundleUnlock instruction. There are no operands.
class InstBundleUnlock : public InstHighLevel {
+ InstBundleUnlock() = delete;
InstBundleUnlock(const InstBundleUnlock &) = delete;
InstBundleUnlock &operator=(const InstBundleUnlock &) = delete;
// eliminated if its dest operand is unused, and therefore the FakeDef
// dest wouldn't be properly initialized.
class InstFakeDef : public InstHighLevel {
+ InstFakeDef() = delete;
InstFakeDef(const InstFakeDef &) = delete;
InstFakeDef &operator=(const InstFakeDef &) = delete;
// situations. The FakeUse instruction has no dest, so it can itself
// never be dead-code eliminated.
class InstFakeUse : public InstHighLevel {
+ InstFakeUse() = delete;
InstFakeUse(const InstFakeUse &) = delete;
InstFakeUse &operator=(const InstFakeUse &) = delete;
// that kills the set of variables, so that if that linked instruction
// gets dead-code eliminated, the FakeKill instruction will as well.
class InstFakeKill : public InstHighLevel {
+ InstFakeKill() = delete;
InstFakeKill(const InstFakeKill &) = delete;
InstFakeKill &operator=(const InstFakeKill &) = delete;
// The Target instruction is the base class for all target-specific
// instructions.
class InstTarget : public Inst {
+ InstTarget() = delete;
InstTarget(const InstTarget &) = delete;
InstTarget &operator=(const InstTarget &) = delete;
// OperandX8632 extends the Operand hierarchy. Its subclasses are
// OperandX8632Mem and VariableSplit.
class OperandX8632 : public Operand {
+ OperandX8632() = delete;
OperandX8632(const OperandX8632 &) = delete;
OperandX8632 &operator=(const OperandX8632 &) = delete;
// base and index registers, a constant offset, and a fixed shift
// value for the index register.
class OperandX8632Mem : public OperandX8632 {
+ OperandX8632Mem() = delete;
OperandX8632Mem(const OperandX8632Mem &) = delete;
OperandX8632Mem &operator=(const OperandX8632Mem &) = delete;
// lowering forces the f64 to be spilled to the stack and then
// accesses through the VariableSplit.
class VariableSplit : public OperandX8632 {
+ VariableSplit() = delete;
VariableSplit(const VariableSplit &) = delete;
VariableSplit &operator=(const VariableSplit &) = delete;
// register. If the linked Variable has a stack slot, then the
// Variable and SpillVariable share that slot.
class SpillVariable : public Variable {
+ SpillVariable() = delete;
SpillVariable(const SpillVariable &) = delete;
SpillVariable &operator=(const SpillVariable &) = delete;
};
class InstX8632 : public InstTarget {
+ InstX8632() = delete;
InstX8632(const InstX8632 &) = delete;
InstX8632 &operator=(const InstX8632 &) = delete;
// it may be prevented by running dead code elimination before
// lowering.
class InstX8632Label : public InstX8632 {
+ InstX8632Label() = delete;
InstX8632Label(const InstX8632Label &) = delete;
InstX8632Label &operator=(const InstX8632Label &) = delete;
// Conditional and unconditional branch instruction.
class InstX8632Br : public InstX8632 {
+ InstX8632Br() = delete;
InstX8632Br(const InstX8632Br &) = delete;
InstX8632Br &operator=(const InstX8632Br &) = delete;
// naclret, unreachable. This is different from a Branch instruction
// in that there is no intra-function control flow to represent.
class InstX8632Jmp : public InstX8632 {
+ InstX8632Jmp() = delete;
InstX8632Jmp(const InstX8632Jmp &) = delete;
InstX8632Jmp &operator=(const InstX8632Jmp &) = delete;
// AdjustStack instruction - subtracts esp by the given amount and
// updates the stack offset during code emission.
class InstX8632AdjustStack : public InstX8632 {
+ InstX8632AdjustStack() = delete;
InstX8632AdjustStack(const InstX8632AdjustStack &) = delete;
InstX8632AdjustStack &operator=(const InstX8632AdjustStack &) = delete;
// Call instruction. Arguments should have already been pushed.
class InstX8632Call : public InstX8632 {
+ InstX8632Call() = delete;
InstX8632Call(const InstX8632Call &) = delete;
InstX8632Call &operator=(const InstX8632Call &) = delete;
// Instructions of the form x := op(x).
template <InstX8632::InstKindX8632 K>
class InstX8632InplaceopGPR : public InstX8632 {
+ InstX8632InplaceopGPR() = delete;
InstX8632InplaceopGPR(const InstX8632InplaceopGPR &) = delete;
InstX8632InplaceopGPR &operator=(const InstX8632InplaceopGPR &) = delete;
// Instructions of the form x := op(y).
template <InstX8632::InstKindX8632 K>
class InstX8632UnaryopGPR : public InstX8632 {
+ InstX8632UnaryopGPR() = delete;
InstX8632UnaryopGPR(const InstX8632UnaryopGPR &) = delete;
InstX8632UnaryopGPR &operator=(const InstX8632UnaryopGPR &) = delete;
template <InstX8632::InstKindX8632 K>
class InstX8632UnaryopXmm : public InstX8632 {
+ InstX8632UnaryopXmm() = delete;
InstX8632UnaryopXmm(const InstX8632UnaryopXmm &) = delete;
InstX8632UnaryopXmm &operator=(const InstX8632UnaryopXmm &) = delete;
template <InstX8632::InstKindX8632 K>
class InstX8632BinopGPRShift : public InstX8632 {
+ InstX8632BinopGPRShift() = delete;
InstX8632BinopGPRShift(const InstX8632BinopGPRShift &) = delete;
InstX8632BinopGPRShift &operator=(const InstX8632BinopGPRShift &) = delete;
template <InstX8632::InstKindX8632 K>
class InstX8632BinopGPR : public InstX8632 {
+ InstX8632BinopGPR() = delete;
InstX8632BinopGPR(const InstX8632BinopGPR &) = delete;
InstX8632BinopGPR &operator=(const InstX8632BinopGPR &) = delete;
template <InstX8632::InstKindX8632 K, bool NeedsElementType>
class InstX8632BinopXmm : public InstX8632 {
+ InstX8632BinopXmm() = delete;
InstX8632BinopXmm(const InstX8632BinopXmm &) = delete;
InstX8632BinopXmm &operator=(const InstX8632BinopXmm &) = delete;
template <InstX8632::InstKindX8632 K>
class InstX8632BinopXmmShift : public InstX8632 {
+ InstX8632BinopXmmShift() = delete;
InstX8632BinopXmmShift(const InstX8632BinopXmmShift &) = delete;
InstX8632BinopXmmShift &operator=(const InstX8632BinopXmmShift &) = delete;
};
template <InstX8632::InstKindX8632 K> class InstX8632Ternop : public InstX8632 {
+ InstX8632Ternop() = delete;
InstX8632Ternop(const InstX8632Ternop &) = delete;
InstX8632Ternop &operator=(const InstX8632Ternop &) = delete;
// Instructions of the form x := y op z
template <InstX8632::InstKindX8632 K>
class InstX8632ThreeAddressop : public InstX8632 {
+ InstX8632ThreeAddressop() = delete;
InstX8632ThreeAddressop(const InstX8632ThreeAddressop &) = delete;
InstX8632ThreeAddressop &operator=(const InstX8632ThreeAddressop &) = delete;
// Base class for assignment instructions
template <InstX8632::InstKindX8632 K>
class InstX8632Movlike : public InstX8632 {
+ InstX8632Movlike() = delete;
InstX8632Movlike(const InstX8632Movlike &) = delete;
InstX8632Movlike &operator=(const InstX8632Movlike &) = delete;
// Base class for a lockable x86-32 instruction (emits a locked prefix).
class InstX8632Lockable : public InstX8632 {
+ InstX8632Lockable() = delete;
InstX8632Lockable(const InstX8632Lockable &) = delete;
InstX8632Lockable &operator=(const InstX8632Lockable &) = delete;
// Mul instruction - unsigned multiply.
class InstX8632Mul : public InstX8632 {
+ InstX8632Mul() = delete;
InstX8632Mul(const InstX8632Mul &) = delete;
InstX8632Mul &operator=(const InstX8632Mul &) = delete;
// Shld instruction - shift across a pair of operands.
class InstX8632Shld : public InstX8632 {
+ InstX8632Shld() = delete;
InstX8632Shld(const InstX8632Shld &) = delete;
InstX8632Shld &operator=(const InstX8632Shld &) = delete;
// Shrd instruction - shift across a pair of operands.
class InstX8632Shrd : public InstX8632 {
+ InstX8632Shrd() = delete;
InstX8632Shrd(const InstX8632Shrd &) = delete;
InstX8632Shrd &operator=(const InstX8632Shrd &) = delete;
// Conditional move instruction.
class InstX8632Cmov : public InstX8632 {
+ InstX8632Cmov() = delete;
InstX8632Cmov(const InstX8632Cmov &) = delete;
InstX8632Cmov &operator=(const InstX8632Cmov &) = delete;
// Cmpps instruction - compare packed singled-precision floating point
// values
class InstX8632Cmpps : public InstX8632 {
+ InstX8632Cmpps() = delete;
InstX8632Cmpps(const InstX8632Cmpps &) = delete;
InstX8632Cmpps &operator=(const InstX8632Cmpps &) = delete;
// <dest> can be a register or memory, while <desired> must be a register.
// It is the user's responsiblity to mark eax with a FakeDef.
class InstX8632Cmpxchg : public InstX8632Lockable {
+ InstX8632Cmpxchg() = delete;
InstX8632Cmpxchg(const InstX8632Cmpxchg &) = delete;
InstX8632Cmpxchg &operator=(const InstX8632Cmpxchg &) = delete;
// and eax as modified.
// <m64> must be a memory operand.
class InstX8632Cmpxchg8b : public InstX8632Lockable {
+ InstX8632Cmpxchg8b() = delete;
InstX8632Cmpxchg8b(const InstX8632Cmpxchg8b &) = delete;
InstX8632Cmpxchg8b &operator=(const InstX8632Cmpxchg8b &) = delete;
// from dest/src types. Sign and zero extension on the integer
// operand needs to be done separately.
class InstX8632Cvt : public InstX8632 {
+ InstX8632Cvt() = delete;
InstX8632Cvt(const InstX8632Cvt &) = delete;
InstX8632Cvt &operator=(const InstX8632Cvt &) = delete;
// cmp - Integer compare instruction.
class InstX8632Icmp : public InstX8632 {
+ InstX8632Icmp() = delete;
InstX8632Icmp(const InstX8632Icmp &) = delete;
InstX8632Icmp &operator=(const InstX8632Icmp &) = delete;
// ucomiss/ucomisd - floating-point compare instruction.
class InstX8632Ucomiss : public InstX8632 {
+ InstX8632Ucomiss() = delete;
InstX8632Ucomiss(const InstX8632Ucomiss &) = delete;
InstX8632Ucomiss &operator=(const InstX8632Ucomiss &) = delete;
// UD2 instruction.
class InstX8632UD2 : public InstX8632 {
+ InstX8632UD2() = delete;
InstX8632UD2(const InstX8632UD2 &) = delete;
InstX8632UD2 &operator=(const InstX8632UD2 &) = delete;
static bool classof(const Inst *Inst) { return isClassof(Inst, UD2); }
private:
- InstX8632UD2(Cfg *Func);
+ explicit InstX8632UD2(Cfg *Func);
~InstX8632UD2() override {}
};
// Test instruction.
class InstX8632Test : public InstX8632 {
+ InstX8632Test() = delete;
InstX8632Test(const InstX8632Test &) = delete;
InstX8632Test &operator=(const InstX8632Test &) = delete;
// Mfence instruction.
class InstX8632Mfence : public InstX8632 {
+ InstX8632Mfence() = delete;
InstX8632Mfence(const InstX8632Mfence &) = delete;
InstX8632Mfence &operator=(const InstX8632Mfence &) = delete;
static bool classof(const Inst *Inst) { return isClassof(Inst, Mfence); }
private:
- InstX8632Mfence(Cfg *Func);
+ explicit InstX8632Mfence(Cfg *Func);
~InstX8632Mfence() override {}
};
// operand instead of Variable as the destination. It's important
// for liveness that there is no Dest operand.
class InstX8632Store : public InstX8632 {
+ InstX8632Store() = delete;
InstX8632Store(const InstX8632Store &) = delete;
InstX8632Store &operator=(const InstX8632Store &) = delete;
// for liveness that there is no Dest operand. The source must be an
// Xmm register, since Dest is mem.
class InstX8632StoreP : public InstX8632 {
+ InstX8632StoreP() = delete;
InstX8632StoreP(const InstX8632StoreP &) = delete;
InstX8632StoreP &operator=(const InstX8632StoreP &) = delete;
};
class InstX8632StoreQ : public InstX8632 {
+ InstX8632StoreQ() = delete;
InstX8632StoreQ(const InstX8632StoreQ &) = delete;
InstX8632StoreQ &operator=(const InstX8632StoreQ &) = delete;
// Nop instructions of varying length
class InstX8632Nop : public InstX8632 {
+ InstX8632Nop() = delete;
InstX8632Nop(const InstX8632Nop &) = delete;
InstX8632Nop &operator=(const InstX8632Nop &) = delete;
// Fld - load a value onto the x87 FP stack.
class InstX8632Fld : public InstX8632 {
+ InstX8632Fld() = delete;
InstX8632Fld(const InstX8632Fld &) = delete;
InstX8632Fld &operator=(const InstX8632Fld &) = delete;
// Fstp - store x87 st(0) into memory and pop st(0).
class InstX8632Fstp : public InstX8632 {
+ InstX8632Fstp() = delete;
InstX8632Fstp(const InstX8632Fstp &) = delete;
InstX8632Fstp &operator=(const InstX8632Fstp &) = delete;
};
class InstX8632Pop : public InstX8632 {
+ InstX8632Pop() = delete;
InstX8632Pop(const InstX8632Pop &) = delete;
InstX8632Pop &operator=(const InstX8632Pop &) = delete;
};
class InstX8632Push : public InstX8632 {
+ InstX8632Push() = delete;
InstX8632Push(const InstX8632Push &) = delete;
InstX8632Push &operator=(const InstX8632Push &) = delete;
// (for non-void returning functions) for liveness analysis, though
// a FakeUse before the ret would do just as well.
class InstX8632Ret : public InstX8632 {
+ InstX8632Ret() = delete;
InstX8632Ret(const InstX8632Ret &) = delete;
InstX8632Ret &operator=(const InstX8632Ret &) = delete;
// Both the dest and source are updated. The caller should then insert a
// FakeDef to reflect the second udpate.
class InstX8632Xadd : public InstX8632Lockable {
+ InstX8632Xadd() = delete;
InstX8632Xadd(const InstX8632Xadd &) = delete;
InstX8632Xadd &operator=(const InstX8632Xadd &) = delete;
// then the instruction is automatically "locked" without the need for
// a lock prefix.
class InstX8632Xchg : public InstX8632 {
+ InstX8632Xchg() = delete;
InstX8632Xchg(const InstX8632Xchg &) = delete;
InstX8632Xchg &operator=(const InstX8632Xchg &) = delete;
namespace Ice {
class Liveness {
+ Liveness() = delete;
Liveness(const Liveness &) = delete;
Liveness &operator=(const Liveness &) = delete;
namespace Ice {
class Operand {
+ Operand() = delete;
Operand(const Operand &) = delete;
Operand &operator=(const Operand &) = delete;
// Constant is the abstract base class for constants. All
// constants are allocated from a global arena and are pooled.
class Constant : public Operand {
+ Constant() = delete;
Constant(const Constant &) = delete;
Constant &operator=(const Constant &) = delete;
// ConstantPrimitive<> wraps a primitive type.
template <typename T, Operand::OperandKind K>
class ConstantPrimitive : public Constant {
+ ConstantPrimitive() = delete;
ConstantPrimitive(const ConstantPrimitive &) = delete;
ConstantPrimitive &operator=(const ConstantPrimitive &) = delete;
// ConstantRelocatable can fit into the global constant pool
// template mechanism.
class RelocatableTuple {
+ RelocatableTuple() = delete;
RelocatableTuple &operator=(const RelocatableTuple &) = delete;
public:
// ConstantRelocatable represents a symbolic constant combined with
// a fixed offset.
class ConstantRelocatable : public Constant {
+ ConstantRelocatable() = delete;
ConstantRelocatable(const ConstantRelocatable &) = delete;
ConstantRelocatable &operator=(const ConstantRelocatable &) = delete;
// legal to lower ConstantUndef to any value, backends should try to
// make code generation deterministic by lowering ConstantUndefs to 0.
class ConstantUndef : public Constant {
+ ConstantUndef() = delete;
ConstantUndef(const ConstantUndef &) = delete;
ConstantUndef &operator=(const ConstantUndef &) = delete;
// special value that represents infinite weight, and an addWeight()
// method that ensures that W+infinity=infinity.
class RegWeight {
-
public:
RegWeight() : Weight(0) {}
- RegWeight(uint32_t Weight) : Weight(Weight) {}
+ explicit RegWeight(uint32_t Weight) : Weight(Weight) {}
RegWeight(const RegWeight &) = default;
RegWeight &operator=(const RegWeight &) = default;
const static uint32_t Inf = ~0; // Force regalloc to give a register
void setWeight(uint32_t Val) { Weight = Val; }
uint32_t getWeight() const { return Weight; }
bool isInf() const { return Weight == Inf; }
+ bool isZero() const { return Weight == Zero; }
private:
uint32_t Weight;
LiveRange() : Weight(0) {}
// Special constructor for building a kill set. The advantage is
// that we can reserve the right amount of space in advance.
- LiveRange(const std::vector<InstNumberT> &Kills) : Weight(0) {
+ explicit LiveRange(const std::vector<InstNumberT> &Kills) : Weight(0) {
Range.reserve(Kills.size());
for (InstNumberT I : Kills)
addSegment(I, I);
// stack-allocated. If it is register-allocated, it will ultimately
// have a non-negative RegNum field.
class Variable : public Operand {
+ Variable() = delete;
Variable(const Variable &) = delete;
Variable &operator=(const Variable &) = delete;
void setRegNumTmp(int32_t NewRegNum) { RegNumTmp = NewRegNum; }
RegWeight getWeight() const { return Weight; }
- void setWeight(uint32_t NewWeight) { Weight = NewWeight; }
- void setWeightInfinite() { Weight = RegWeight::Inf; }
+ void setWeight(uint32_t NewWeight) { Weight = RegWeight(NewWeight); }
+ void setWeightInfinite() { setWeight(RegWeight::Inf); }
LiveRange &getLiveRange() { return Live; }
const LiveRange &getLiveRange() const { return Live; }
assert(WeightDelta != RegWeight::Inf);
Live.addSegment(Start, End);
if (Weight.isInf())
- Live.setWeight(RegWeight::Inf);
+ Live.setWeight(RegWeight(RegWeight::Inf));
else
Live.addWeight(WeightDelta * Weight.getWeight());
}
- void setLiveRangeInfiniteWeight() { Live.setWeight(RegWeight::Inf); }
+ void setLiveRangeInfiniteWeight() {
+ Live.setWeight(RegWeight(RegWeight::Inf));
+ }
void trimLiveRange(InstNumberT Start) { Live.trim(Start); }
void untrimLiveRange() { Live.untrim(); }
bool rangeEndsBefore(const Variable *Other) const {
// VariablesMetadata analyzes and summarizes the metadata for the
// complete set of Variables.
class VariablesMetadata {
+ VariablesMetadata() = delete;
VariablesMetadata(const VariablesMetadata &) = delete;
VariablesMetadata &operator=(const VariablesMetadata &) = delete;
public:
- VariablesMetadata(const Cfg *Func) : Func(Func) {}
+ explicit VariablesMetadata(const Cfg *Func) : Func(Func) {}
// Initialize the state by traversing all instructions/variables in
// the CFG.
void init(MetadataKind TrackingKind);
namespace Ice {
class RandomNumberGenerator {
+ RandomNumberGenerator() = delete;
RandomNumberGenerator(const RandomNumberGenerator &) = delete;
RandomNumberGenerator &operator=(const RandomNumberGenerator &) = delete;
public:
- RandomNumberGenerator(llvm::StringRef Salt);
+ explicit RandomNumberGenerator(llvm::StringRef Salt);
uint64_t next(uint64_t Max);
private:
// reason for the wrapper class is that we want to keep the
// RandomNumberGenerator interface identical to LLVM's.
class RandomNumberGeneratorWrapper {
+ RandomNumberGeneratorWrapper() = delete;
RandomNumberGeneratorWrapper(const RandomNumberGeneratorWrapper &) = delete;
RandomNumberGeneratorWrapper &
operator=(const RandomNumberGeneratorWrapper &) = delete;
public:
uint64_t operator()(uint64_t Max) { return RNG.next(Max); }
bool getTrueWithProbability(float Probability);
- RandomNumberGeneratorWrapper(RandomNumberGenerator &RNG) : RNG(RNG) {}
+ explicit RandomNumberGeneratorWrapper(RandomNumberGenerator &RNG)
+ : RNG(RNG) {}
private:
RandomNumberGenerator &RNG;
for (Variable *Var : Vars) {
// Explicitly don't consider zero-weight variables, which are
// meant to be spill slots.
- if (Var->getWeight() == RegWeight::Zero)
+ if (Var->getWeight().isZero())
continue;
// Don't bother if the variable has a null live range, which means
// it was never referenced.
if (Inst.isDeleted())
continue;
if (const Variable *Var = Inst.getDest()) {
- if (Var->hasReg() || Var->getWeight() == RegWeight::Inf) {
+ if (Var->hasReg() || Var->getWeight().isInf()) {
if (LRBegin[Var->getIndex()] == Inst::NumberSentinel) {
LRBegin[Var->getIndex()] = Inst.getNumber();
++NumVars;
SizeT NumVars = Src->getNumVars();
for (SizeT J = 0; J < NumVars; ++J) {
const Variable *Var = Src->getVar(J);
- if (Var->hasReg() || Var->getWeight() == RegWeight::Inf)
+ if (Var->hasReg() || Var->getWeight().isInf())
LREnd[Var->getIndex()] = Inst.getNumber();
}
}
namespace Ice {
class LinearScan {
+ LinearScan() = delete;
LinearScan(const LinearScan &) = delete;
LinearScan &operator=(const LinearScan &) = delete;
public:
- LinearScan(Cfg *Func)
+ explicit LinearScan(Cfg *Func)
: Func(Func), FindPreference(false), FindOverlap(false) {}
void init(RegAllocKind Kind);
void scan(const llvm::SmallBitVector &RegMask, bool Randomized);
};
class TargetLowering {
+ TargetLowering() = delete;
TargetLowering(const TargetLowering &) = delete;
TargetLowering &operator=(const TargetLowering &) = delete;
virtual ~TargetLowering() {}
protected:
- TargetLowering(Cfg *Func);
+ explicit TargetLowering(Cfg *Func);
virtual void lowerAlloca(const InstAlloca *Inst) = 0;
virtual void lowerArithmetic(const InstArithmetic *Inst) = 0;
virtual void lowerAssign(const InstAssign *Inst) = 0;
virtual void lowerConstants() const = 0;
protected:
- TargetDataLowering(GlobalContext *Ctx) : Ctx(Ctx) {}
+ explicit TargetDataLowering(GlobalContext *Ctx) : Ctx(Ctx) {}
GlobalContext *Ctx;
};
// A spill slot linked to a variable with a stack slot should reuse
// that stack slot.
if (SpillVariable *SpillVar = llvm::dyn_cast<SpillVariable>(Var)) {
- assert(Var->getWeight() == RegWeight::Zero);
+ assert(Var->getWeight().isZero());
if (!SpillVar->getLinkedTo()->hasReg()) {
VariablesLinkedToSpillSlots.push_back(Var);
continue;
Variable *Slot,
uint32_t Offset) {
// Ensure that Loc is a stack slot.
- assert(Slot->getWeight() == RegWeight::Zero);
+ assert(Slot->getWeight().isZero());
assert(Slot->getRegNum() == Variable::NoRegister);
// Compute the location of Loc in memory.
// TODO(wala,stichnot): lea should not be required. The address of
// Check if the variable is guaranteed a physical register. This
// can happen either when the variable is pre-colored or when it is
// assigned infinite weight.
- bool MustHaveRegister =
- (Var->hasReg() || Var->getWeight() == RegWeight::Inf);
+ bool MustHaveRegister = (Var->hasReg() || Var->getWeight().isInf());
// We need a new physical register for the operand if:
// Mem is not allowed and Var isn't guaranteed a physical
// register, or
namespace Ice {
class TargetX8632 : public TargetLowering {
+ TargetX8632() = delete;
TargetX8632(const TargetX8632 &) = delete;
TargetX8632 &operator=(const TargetX8632 &) = delete;
X86InstructionSet getInstructionSet() const { return InstructionSet; }
protected:
- TargetX8632(Cfg *Func);
+ explicit TargetX8632(Cfg *Func);
void postLower() override;
void lowerConstants() const final;
protected:
- TargetDataX8632(GlobalContext *Ctx);
+ explicit TargetDataX8632(GlobalContext *Ctx);
private:
void lowerGlobal(const VariableDeclaration &Var) const;
namespace Ice {
class TimerStack {
+ TimerStack() = delete;
TimerStack &operator=(const TimerStack &) = delete;
// Timer tree index type. A variable of this type is used to access
#undef X
TT__num
};
- TimerStack(const IceString &Name);
+ explicit TimerStack(const IceString &Name);
TimerStack(const TimerStack &) = default;
TimerIdT getTimerID(const IceString &Name);
void mergeFrom(const TimerStack &Src);
// other intermediate representations down to ICE, and then call the appropriate
// (inherited) methods to convert ICE into machine instructions.
class Translator {
+ Translator() = delete;
Translator(const Translator &) = delete;
Translator &operator=(const Translator &) = delete;
public:
- Translator(GlobalContext *Ctx);
+ explicit Translator(GlobalContext *Ctx);
~Translator();
const ErrorCode &getErrorStatus() const { return ErrorStatus; }
/// Converts LLVM types to ICE types, and ICE types to LLVM types.
class TypeConverter {
+ TypeConverter() = delete;
TypeConverter(const TypeConverter &) = delete;
TypeConverter &operator=(const TypeConverter &) = delete;
public:
/// Context is the context to use to build llvm types.
- TypeConverter(llvm::LLVMContext &Context);
+ explicit TypeConverter(llvm::LLVMContext &Context);
/// Converts LLVM type LLVMTy to an ICE type. Returns
/// Ice::IceType_NUM if unable to convert.
}
class Utils {
+ Utils() = delete;
+ Utils(const Utils &) = delete;
+ Utils &operator=(const Utils &) = delete;
+
public:
// Check whether an N-bit two's-complement representation can hold value.
template <typename T> static inline bool IsInt(int N, T value) {
// Models an ICE type as an extended type.
class SimpleExtendedType : public ExtendedType {
+ SimpleExtendedType() = delete;
SimpleExtendedType(const SimpleExtendedType &) = delete;
SimpleExtendedType &operator=(const SimpleExtendedType &) = delete;
// Models a function signature as an extended type.
class FuncSigExtendedType : public ExtendedType {
+ FuncSigExtendedType() = delete;
FuncSigExtendedType(const FuncSigExtendedType &) = delete;
FuncSigExtendedType &operator=(const FuncSigExtendedType &) = delete;
// Top-level class to read PNaCl bitcode files, and translate to ICE.
class TopLevelParser : public NaClBitcodeParser {
+ TopLevelParser() = delete;
TopLevelParser(const TopLevelParser &) = delete;
TopLevelParser &operator=(const TopLevelParser &) = delete;
// messages if ParseBlock or ParseRecord is not overridden in derived
// classes.
class BlockParserBaseClass : public NaClBitcodeParser {
+ BlockParserBaseClass() = delete;
BlockParserBaseClass(const BlockParserBaseClass &) = delete;
BlockParserBaseClass &operator=(const BlockParserBaseClass &) = delete;
// Class to parse a types block.
class TypesParser : public BlockParserBaseClass {
+ TypesParser() = delete;
+ TypesParser(const TypesParser &) = delete;
+ TypesParser &operator=(const TypesParser &) = delete;
+
public:
TypesParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
: BlockParserBaseClass(BlockID, EnclosingParser),
/// Parses the globals block (i.e. global variable declarations and
/// corresponding initializers).
class GlobalsParser : public BlockParserBaseClass {
+ GlobalsParser() = delete;
+ GlobalsParser(const GlobalsParser &) = delete;
+ GlobalsParser &operator=(const GlobalsParser &) = delete;
+
public:
GlobalsParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
: BlockParserBaseClass(BlockID, EnclosingParser),
/// Base class for parsing a valuesymtab block in the bitcode file.
class ValuesymtabParser : public BlockParserBaseClass {
+ ValuesymtabParser() = delete;
ValuesymtabParser(const ValuesymtabParser &) = delete;
void operator=(const ValuesymtabParser &) = delete;
/// Parses function blocks in the bitcode file.
class FunctionParser : public BlockParserBaseClass {
+ FunctionParser() = delete;
FunctionParser(const FunctionParser &) = delete;
FunctionParser &operator=(const FunctionParser &) = delete;
/// Parses constants within a function block.
class ConstantsParser : public BlockParserBaseClass {
+ ConstantsParser() = delete;
ConstantsParser(const ConstantsParser &) = delete;
ConstantsParser &operator=(const ConstantsParser &) = delete;
// Parses valuesymtab blocks appearing in a function block.
class FunctionValuesymtabParser : public ValuesymtabParser {
+ FunctionValuesymtabParser() = delete;
FunctionValuesymtabParser(const FunctionValuesymtabParser &) = delete;
void operator=(const FunctionValuesymtabParser &) = delete;
/// Parses the module block in the bitcode file.
class ModuleParser : public BlockParserBaseClass {
+ ModuleParser() = delete;
+ ModuleParser(const ModuleParser &) = delete;
+ ModuleParser &operator=(const ModuleParser &) = delete;
+
public:
ModuleParser(unsigned BlockID, TopLevelParser *Context)
: BlockParserBaseClass(BlockID, Context),
};
class ModuleValuesymtabParser : public ValuesymtabParser {
+ ModuleValuesymtabParser() = delete;
ModuleValuesymtabParser(const ModuleValuesymtabParser &) = delete;
void operator=(const ModuleValuesymtabParser &) = delete;
namespace Ice {
class PNaClTranslator : public Translator {
+ PNaClTranslator() = delete;
PNaClTranslator(const PNaClTranslator &) = delete;
PNaClTranslator &operator=(const PNaClTranslator &) = delete;
public:
- PNaClTranslator(GlobalContext *Ctx) : Translator(Ctx) {}
+ explicit PNaClTranslator(GlobalContext *Ctx) : Translator(Ctx) {}
// Reads the PNaCl bitcode file and translates to ICE, which is then
// converted to machine code. Sets ErrorStatus to 1 if any errors