Commit 1bec8bcd by John Porto

Subzero. Fixes memory leaks.

Adds named constructors to initialzers. Removes destructor from Inst. BUG= None R=stichnot@chromium.org Review URL: https://codereview.chromium.org/1181013016.
parent 8525c329
......@@ -77,11 +77,12 @@ namespace {
constexpr char BlockNameGlobalPrefix[] = ".L$profiler$block_name$";
constexpr char BlockStatsGlobalPrefix[] = ".L$profiler$block_info$";
VariableDeclaration *nodeNameDeclaration(const IceString &NodeAsmName) {
VariableDeclaration *Var = VariableDeclaration::create();
VariableDeclaration *nodeNameDeclaration(GlobalContext *Ctx,
const IceString &NodeAsmName) {
VariableDeclaration *Var = VariableDeclaration::create(Ctx);
Var->setName(BlockNameGlobalPrefix + NodeAsmName);
Var->setIsConstant(true);
Var->addInitializer(new VariableDeclaration::DataInitializer(
Var->addInitializer(VariableDeclaration::DataInitializer::create(
NodeAsmName.data(), NodeAsmName.size() + 1));
const SizeT Int64ByteSize = typeWidthInBytes(IceType_i64);
Var->setAlignment(Int64ByteSize); // Wasteful, 32-bit could use 4 bytes.
......@@ -89,20 +90,20 @@ VariableDeclaration *nodeNameDeclaration(const IceString &NodeAsmName) {
}
VariableDeclaration *
blockProfilingInfoDeclaration(const IceString &NodeAsmName,
blockProfilingInfoDeclaration(GlobalContext *Ctx, const IceString &NodeAsmName,
VariableDeclaration *NodeNameDeclaration) {
VariableDeclaration *Var = VariableDeclaration::create();
VariableDeclaration *Var = VariableDeclaration::create(Ctx);
Var->setName(BlockStatsGlobalPrefix + NodeAsmName);
const SizeT Int64ByteSize = typeWidthInBytes(IceType_i64);
Var->addInitializer(new VariableDeclaration::ZeroInitializer(Int64ByteSize));
Var->addInitializer(
VariableDeclaration::ZeroInitializer::create(Int64ByteSize));
const RelocOffsetT NodeNameDeclarationOffset = 0;
Var->addInitializer(new VariableDeclaration::RelocInitializer(
Var->addInitializer(VariableDeclaration::RelocInitializer::create(
NodeNameDeclaration, NodeNameDeclarationOffset));
Var->setAlignment(Int64ByteSize);
return Var;
}
} // end of anonymous namespace
void Cfg::profileBlocks() {
......@@ -111,9 +112,9 @@ void Cfg::profileBlocks() {
for (CfgNode *Node : Nodes) {
IceString NodeAsmName = Node->getAsmName();
GlobalInits->push_back(nodeNameDeclaration(NodeAsmName));
GlobalInits->push_back(nodeNameDeclaration(Ctx, NodeAsmName));
GlobalInits->push_back(
blockProfilingInfoDeclaration(NodeAsmName, GlobalInits->back()));
blockProfilingInfoDeclaration(Ctx, NodeAsmName, GlobalInits->back()));
Node->profileExecutionCount(GlobalInits->back());
}
}
......
......@@ -754,7 +754,7 @@ void LLVM2ICEGlobalsConverter::addGlobalInitializer(
if (const auto CDA = dyn_cast<ConstantDataArray>(Initializer)) {
assert(!HasOffset && isa<IntegerType>(CDA->getElementType()) &&
(cast<IntegerType>(CDA->getElementType())->getBitWidth() == 8));
Global.addInitializer(new Ice::VariableDeclaration::DataInitializer(
Global.addInitializer(Ice::VariableDeclaration::DataInitializer::create(
CDA->getRawDataValues().data(), CDA->getNumElements()));
return;
}
......@@ -763,8 +763,8 @@ void LLVM2ICEGlobalsConverter::addGlobalInitializer(
if (const auto AT = dyn_cast<ArrayType>(Initializer->getType())) {
assert(!HasOffset && isa<IntegerType>(AT->getElementType()) &&
(cast<IntegerType>(AT->getElementType())->getBitWidth() == 8));
Global.addInitializer(
new Ice::VariableDeclaration::ZeroInitializer(AT->getNumElements()));
Global.addInitializer(Ice::VariableDeclaration::ZeroInitializer::create(
AT->getNumElements()));
} else {
llvm_unreachable("Unhandled constant aggregate zero type");
}
......@@ -786,7 +786,7 @@ void LLVM2ICEGlobalsConverter::addGlobalInitializer(
const Ice::GlobalDeclaration *Addr =
getConverter().getGlobalDeclaration(GV);
Global.addInitializer(
new Ice::VariableDeclaration::RelocInitializer(Addr, Offset));
Ice::VariableDeclaration::RelocInitializer::create(Addr, Offset));
return;
}
default:
......@@ -867,7 +867,7 @@ void Converter::installGlobalDeclarations(Module *Mod) {
Converter.convertToIceType(FuncType->getParamType(I)));
}
FunctionDeclaration *IceFunc = FunctionDeclaration::create(
Signature, Func.getCallingConv(), Func.getLinkage(), Func.empty());
Ctx, Signature, Func.getCallingConv(), Func.getLinkage(), Func.empty());
IceFunc->setName(Func.getName());
GlobalDeclarationMap[&Func] = IceFunc;
}
......@@ -876,7 +876,7 @@ void Converter::installGlobalDeclarations(Module *Mod) {
E = Mod->global_end();
I != E; ++I) {
const GlobalVariable *GV = I;
VariableDeclaration *Var = VariableDeclaration::create();
VariableDeclaration *Var = VariableDeclaration::create(Ctx);
Var->setName(GV->getName());
Var->setAlignment(GV->getAlignment());
Var->setIsConstant(GV->isConstant());
......
......@@ -93,6 +93,46 @@ inline bool operator!=(const CfgLocalAllocator<T> &,
return false;
}
// makeUnique should be used when memory is expected to be allocated from the
// heap (as opposed to allocated from some Allocator.) It is intended to be used
// instead of new.
//
// The expected usage is as follows
//
// class MyClass {
// public:
// static std::unique_ptr<MyClass> create(<ctor_args>) {
// return makeUnique<MyClass>(<ctor_args>);
// }
//
// private:
// ENABLE_MAKE_UNIQUE;
//
// MyClass(<ctor_args>) ...
// }
//
// ENABLE_MAKE_UNIQUE is a trick that is necessary if MyClass' ctor is private.
// Private ctors are highly encouraged when you're writing a class that you'd
// like to have allocated with makeUnique as it would prevent users from
// declaring stack allocated variables.
namespace Internal {
struct MakeUniqueEnabler {
template <class T, class... Args>
static std::unique_ptr<T> create(Args &&... TheArgs) {
std::unique_ptr<T> Unique(new T(std::forward<Args>(TheArgs)...));
return Unique;
}
};
} // end of namespace Internal
template <class T, class... Args>
static std::unique_ptr<T> makeUnique(Args &&... TheArgs) {
return ::Ice::Internal::MakeUniqueEnabler::create<T>(
std::forward<Args>(TheArgs)...);
}
#define ENABLE_MAKE_UNIQUE friend struct ::Ice::Internal::MakeUniqueEnabler
typedef std::string IceString;
typedef llvm::ilist<Inst> InstList;
// Ideally PhiList would be llvm::ilist<InstPhi>, and similar for
......
......@@ -386,12 +386,12 @@ void ELFObjectWriter::writeDataOfType(SectionType ST,
Section->setSize(Section->getCurrentSize() + SymbolSize);
} else {
assert(ST != BSS);
for (VariableDeclaration::Initializer *Init : Var->getInitializers()) {
for (const std::unique_ptr<VariableDeclaration::Initializer> &Init :
Var->getInitializers()) {
switch (Init->getKind()) {
case VariableDeclaration::Initializer::DataInitializerKind: {
const auto Data =
llvm::cast<VariableDeclaration::DataInitializer>(Init)
->getContents();
const auto Data = llvm::cast<VariableDeclaration::DataInitializer>(
Init.get())->getContents();
Section->appendData(Str, llvm::StringRef(Data.data(), Data.size()));
break;
}
......@@ -400,7 +400,7 @@ void ELFObjectWriter::writeDataOfType(SectionType ST,
break;
case VariableDeclaration::Initializer::RelocInitializerKind: {
const auto Reloc =
llvm::cast<VariableDeclaration::RelocInitializer>(Init);
llvm::cast<VariableDeclaration::RelocInitializer>(Init.get());
AssemblerFixup NewFixup;
NewFixup.set_position(Section->getCurrentSize());
NewFixup.set_kind(RelocationKind);
......
......@@ -33,6 +33,8 @@ class ELFSection {
ELFSection &operator=(const ELFSection &) = delete;
public:
virtual ~ELFSection() = default;
// Sentinel value for a section number/index for before the final
// section index is actually known. The dummy NULL section will be assigned
// number 0, and it is referenced by the dummy 0-th symbol in the symbol
......@@ -81,8 +83,6 @@ public:
template <bool IsELF64> void writeHeader(ELFStreamer &Str);
protected:
~ELFSection() = default;
// Name of the section in convenient string form (instead of a index
// into the Section Header String Table, which is not known till later).
const IceString Name;
......
......@@ -223,8 +223,7 @@ GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError,
/*MaxSize=*/Flags.getNumTranslationThreads()),
// EmitQ is allowed unlimited size.
EmitQ(/*Sequential=*/Flags.isSequential()),
DataLowering(TargetDataLowering::createLowering(this)),
ProfileBlockInfoVarDecl(VariableDeclaration::create()) {
DataLowering(TargetDataLowering::createLowering(this)) {
assert(OsDump && "OsDump is not defined for GlobalContext");
assert(OsEmit && "OsEmit is not defined for GlobalContext");
assert(OsError && "OsError is not defined for GlobalContext");
......@@ -256,6 +255,11 @@ GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError,
case FT_Iasm:
break;
}
// ProfileBlockInfoVarDecl is initialized here because it takes this as a
// parameter -- we want to
// ensure that at least this' member variables are initialized.
ProfileBlockInfoVarDecl = VariableDeclaration::create(this);
ProfileBlockInfoVarDecl->setAlignment(typeWidthInBytes(IceType_i64));
ProfileBlockInfoVarDecl->setIsConstant(true);
......@@ -346,7 +350,7 @@ void addBlockInfoPtrs(const VariableDeclarationList &Globals,
if (Cfg::isProfileGlobal(*Global)) {
constexpr RelocOffsetT BlockExecutionCounterOffset = 0;
ProfileBlockInfo->addInitializer(
new VariableDeclaration::RelocInitializer(
VariableDeclaration::RelocInitializer::create(
Global, BlockExecutionCounterOffset));
}
}
......@@ -387,20 +391,28 @@ void GlobalContext::lowerGlobals(const IceString &SectionSuffix) {
if (Flags.getDisableTranslation())
return;
addBlockInfoPtrs(Globals, ProfileBlockInfoVarDecl.get());
addBlockInfoPtrs(Globals, ProfileBlockInfoVarDecl);
DataLowering->lowerGlobals(Globals, SectionSuffix);
for (VariableDeclaration *Var : Globals) {
Var->discardInitializers();
}
Globals.clear();
}
void GlobalContext::lowerProfileData() {
// ProfileBlockInfoVarDecl is initialized in the constructor, and will only
// ever be nullptr after this method completes. This assertion is a convoluted
// way of ensuring lowerProfileData is invoked a single time.
assert(ProfileBlockInfoVarDecl != nullptr);
// This adds a 64-bit sentinel entry to the end of our array. For 32-bit
// architectures this will waste 4 bytes.
const SizeT Sizeof64BitNullPtr = typeWidthInBytes(IceType_i64);
ProfileBlockInfoVarDecl->addInitializer(
new VariableDeclaration::ZeroInitializer(Sizeof64BitNullPtr));
Globals.push_back(ProfileBlockInfoVarDecl.get());
VariableDeclaration::ZeroInitializer::create(Sizeof64BitNullPtr));
Globals.push_back(ProfileBlockInfoVarDecl);
constexpr char ProfileDataSection[] = "$sz_profiler$";
lowerGlobals(ProfileDataSection);
ProfileBlockInfoVarDecl = nullptr;
}
void GlobalContext::emitItems() {
......@@ -649,6 +661,12 @@ IceString GlobalContext::mangleName(const IceString &Name) const {
GlobalContext::~GlobalContext() {
llvm::DeleteContainerPointers(AllThreadContexts);
LockedPtr<DestructorArray> Dtors = getDestructors();
// Destructors are invoked in the opposite object construction order.
for (auto DtorIter = Dtors->crbegin(); DtorIter != Dtors->crend();
++DtorIter) {
(*DtorIter)();
}
}
// TODO(stichnot): Consider adding thread-local caches of constant
......
......@@ -16,8 +16,11 @@
#define SUBZERO_SRC_ICEGLOBALCONTEXT_H
#include <array>
#include <functional>
#include <mutex>
#include <thread>
#include <type_traits>
#include <vector>
#include "IceDefs.h"
#include "IceClFlags.h"
......@@ -211,8 +214,24 @@ public:
return getFlags().getDisableIRGeneration();
}
// Allocate data of type T using the global allocator.
template <typename T> T *allocate() { return getAllocator()->Allocate<T>(); }
// Allocate data of type T using the global allocator. We allow entities
// allocated from this global allocator to be either trivially or
// non-trivially destructible. We optimize the case when T is trivially
// destructible by not registering a destructor. Destructors will be invoked
// during GlobalContext destruction in the reverse object creation order.
template <typename T>
typename std::enable_if<std::is_trivially_destructible<T>::value, T>::type *
allocate() {
return getAllocator()->Allocate<T>();
}
template <typename T>
typename std::enable_if<!std::is_trivially_destructible<T>::value, T>::type *
allocate() {
T *Ret = getAllocator()->Allocate<T>();
getDestructors()->emplace_back([Ret]() { Ret->~T(); });
return Ret;
}
const Intrinsics &getIntrinsicsInfo() const { return IntrinsicsInfo; }
......@@ -392,8 +411,9 @@ public:
// until the queue is empty.
void emitItems();
// Uses DataLowering to lower Globals. As a side effect, clears the Globals
// array.
// Uses DataLowering to lower Globals. Side effects:
// - discards the initializer list for the global variable in Globals.
// - clears the Globals array.
void lowerGlobals(const IceString &SectionSuffix);
// Lowers the profile information.
......@@ -417,12 +437,19 @@ public:
private:
// Try to ensure mutexes are allocated on separate cache lines.
// Destructors collaborate with Allocator
ICE_CACHELINE_BOUNDARY;
// Managed by getAllocator()
GlobalLockType AllocLock;
ArenaAllocator<> Allocator;
ICE_CACHELINE_BOUNDARY;
// Managed by getDestructors()
typedef std::vector<std::function<void()>> DestructorArray;
GlobalLockType DestructorsLock;
DestructorArray Destructors;
ICE_CACHELINE_BOUNDARY;
// Managed by getConstantPool()
GlobalLockType ConstPoolLock;
std::unique_ptr<ConstantPool> ConstPool;
......@@ -470,7 +497,7 @@ private:
// TODO(jpp): move to EmitterContext.
VariableDeclarationList Globals;
// TODO(jpp): move to EmitterContext.
std::unique_ptr<VariableDeclaration> ProfileBlockInfoVarDecl;
VariableDeclaration *ProfileBlockInfoVarDecl;
LockedPtr<ArenaAllocator<>> getAllocator() {
return LockedPtr<ArenaAllocator<>>(&Allocator, &AllocLock);
......@@ -484,6 +511,9 @@ private:
LockedPtr<TimerList> getTimers() {
return LockedPtr<TimerList>(&Timers, &TimerLock);
}
LockedPtr<DestructorArray> getDestructors() {
return LockedPtr<DestructorArray>(&Destructors, &DestructorsLock);
}
void accumulateGlobals(std::unique_ptr<VariableDeclarationList> Globls) {
if (Globls != nullptr)
......
......@@ -60,12 +60,6 @@ void dumpCallingConv(Ice::Ostream &, llvm::CallingConv::ID CallingConv) {
namespace Ice {
FunctionDeclaration *FunctionDeclaration::create(
const FuncSigType &Signature, llvm::CallingConv::ID CallingConv,
llvm::GlobalValue::LinkageTypes Linkage, bool IsProto) {
return new FunctionDeclaration(Signature, CallingConv, Linkage, IsProto);
}
void FunctionDeclaration::dumpType(Ostream &Stream) const {
if (!ALLOW_DUMP)
return;
......@@ -92,23 +86,15 @@ void FunctionDeclaration::dump(GlobalContext *Ctx, Ostream &Stream) const {
Stream << ")";
}
VariableDeclaration *VariableDeclaration::create() {
return new VariableDeclaration();
}
VariableDeclaration::~VariableDeclaration() {
llvm::DeleteContainerPointers(Initializers);
}
void VariableDeclaration::dumpType(Ostream &Stream) const {
if (!ALLOW_DUMP)
return;
if (Initializers.size() == 1) {
Initializers.front()->dumpType(Stream);
if (Initializers->size() == 1) {
Initializers->front()->dumpType(Stream);
} else {
Stream << "<{ ";
bool IsFirst = true;
for (Initializer *Init : Initializers) {
for (const std::unique_ptr<Initializer> &Init : *Initializers) {
if (IsFirst) {
IsFirst = false;
} else {
......@@ -130,13 +116,13 @@ void VariableDeclaration::dump(GlobalContext *Ctx, Ostream &Stream) const {
Stream << " " << (IsConstant ? "constant" : "global") << " ";
// Add initializer.
if (Initializers.size() == 1) {
Initializers.front()->dump(Stream);
if (Initializers->size() == 1) {
Initializers->front()->dump(Stream);
} else {
dumpType(Stream);
Stream << " <{ ";
bool IsFirst = true;
for (Initializer *Init : Initializers) {
for (const std::unique_ptr<Initializer> &Init : *Initializers) {
if (IsFirst) {
IsFirst = false;
} else {
......
......@@ -17,8 +17,12 @@
#ifndef SUBZERO_SRC_ICEGLOBALINITS_H
#define SUBZERO_SRC_ICEGLOBALINITS_H
#include <memory>
#include <utility>
#include "llvm/Bitcode/NaCl/NaClBitcodeParser.h" // for NaClBitcodeRecord.
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/GlobalValue.h" // for GlobalValue::LinkageTypes
#include "llvm/IR/GlobalValue.h" // for GlobalValue::LinkageTypes.
#include "IceDefs.h"
#include "IceTypes.h"
......@@ -95,11 +99,14 @@ class FunctionDeclaration : public GlobalDeclaration {
FunctionDeclaration &operator=(const FunctionDeclaration &) = delete;
public:
static FunctionDeclaration *create(const FuncSigType &Signature,
static FunctionDeclaration *create(GlobalContext *Context,
const FuncSigType &Signature,
llvm::CallingConv::ID CallingConv,
llvm::GlobalValue::LinkageTypes Linkage,
bool IsProto);
~FunctionDeclaration() final {}
bool IsProto) {
return new (Context->allocate<FunctionDeclaration>())
FunctionDeclaration(Signature, CallingConv, Linkage, IsProto);
}
const FuncSigType &getSignature() const { return Signature; }
llvm::CallingConv::ID getCallingConv() const { return CallingConv; }
// isProto implies that there isn't a (local) definition for the function.
......@@ -167,21 +174,11 @@ public:
DataInitializer &operator=(const DataInitializer &) = delete;
public:
template <class IntContainer>
DataInitializer(const IntContainer &Values)
: Initializer(DataInitializerKind), Contents(Values.size()) {
size_t i = 0;
for (auto &V : Values) {
Contents[i] = static_cast<int8_t>(V);
++i;
}
template <class... Args>
static std::unique_ptr<DataInitializer> create(Args &&... TheArgs) {
return makeUnique<DataInitializer>(std::forward<Args>(TheArgs)...);
}
DataInitializer(const char *Str, size_t StrLen)
: Initializer(DataInitializerKind), Contents(StrLen) {
for (size_t i = 0; i < StrLen; ++i)
Contents[i] = Str[i];
}
~DataInitializer() override {}
const DataVecType &getContents() const { return Contents; }
SizeT getNumBytes() const final { return Contents.size(); }
void dump(GlobalContext *Ctx, Ostream &Stream) const final;
......@@ -190,6 +187,20 @@ public:
}
private:
ENABLE_MAKE_UNIQUE;
DataInitializer(const llvm::NaClBitcodeRecord::RecordVector &Values)
: Initializer(DataInitializerKind), Contents(Values.size()) {
for (SizeT I = 0; I < Values.size(); ++I)
Contents[I] = static_cast<int8_t>(Values[I]);
}
DataInitializer(const char *Str, size_t StrLen)
: Initializer(DataInitializerKind), Contents(StrLen) {
for (size_t i = 0; i < StrLen; ++i)
Contents[i] = Str[i];
}
// The byte contents of the data initializer.
DataVecType Contents;
};
......@@ -200,9 +211,9 @@ public:
ZeroInitializer &operator=(const ZeroInitializer &) = delete;
public:
explicit ZeroInitializer(SizeT Size)
: Initializer(ZeroInitializerKind), Size(Size) {}
~ZeroInitializer() override {}
static std::unique_ptr<ZeroInitializer> create(SizeT Size) {
return makeUnique<ZeroInitializer>(Size);
}
SizeT getNumBytes() const final { return Size; }
void dump(GlobalContext *Ctx, Ostream &Stream) const final;
static bool classof(const Initializer *Z) {
......@@ -210,6 +221,11 @@ public:
}
private:
ENABLE_MAKE_UNIQUE;
explicit ZeroInitializer(SizeT Size)
: Initializer(ZeroInitializerKind), Size(Size) {}
// The number of bytes to be zero initialized.
SizeT Size;
};
......@@ -220,10 +236,11 @@ public:
RelocInitializer &operator=(const RelocInitializer &) = delete;
public:
RelocInitializer(const GlobalDeclaration *Declaration, RelocOffsetT Offset)
: Initializer(RelocInitializerKind), Declaration(Declaration),
Offset(Offset) {}
~RelocInitializer() override {}
static std::unique_ptr<RelocInitializer>
create(const GlobalDeclaration *Declaration, RelocOffsetT Offset) {
return makeUnique<RelocInitializer>(Declaration, Offset);
}
RelocOffsetT getOffset() const { return Offset; }
const GlobalDeclaration *getDeclaration() const { return Declaration; }
SizeT getNumBytes() const final { return RelocAddrSize; }
......@@ -234,34 +251,40 @@ public:
}
private:
// The global declaration used in the relocation.
ENABLE_MAKE_UNIQUE;
RelocInitializer(const GlobalDeclaration *Declaration, RelocOffsetT Offset)
: Initializer(RelocInitializerKind), Declaration(Declaration),
Offset(Offset) {} // The global declaration used in the relocation.
const GlobalDeclaration *Declaration;
// The offset to add to the relocation.
const RelocOffsetT Offset;
};
/// Models the list of initializers.
typedef std::vector<Initializer *> InitializerListType;
typedef std::vector<std::unique_ptr<Initializer>> InitializerListType;
static VariableDeclaration *create();
~VariableDeclaration() final;
static VariableDeclaration *create(GlobalContext *Context) {
return new (Context->allocate<VariableDeclaration>()) VariableDeclaration();
}
const InitializerListType &getInitializers() const { return Initializers; }
const InitializerListType &getInitializers() const { return *Initializers; }
bool getIsConstant() const { return IsConstant; }
void setIsConstant(bool NewValue) { IsConstant = NewValue; }
uint32_t getAlignment() const { return Alignment; }
void setAlignment(uint32_t NewAlignment) { Alignment = NewAlignment; }
bool hasInitializer() const { return !Initializers.empty(); }
bool hasInitializer() const { return HasInitializer; }
bool hasNonzeroInitializer() const {
return !(Initializers.size() == 1 &&
llvm::isa<ZeroInitializer>(Initializers[0]));
return !(Initializers->size() == 1 &&
llvm::isa<ZeroInitializer>((*Initializers)[0].get()));
}
/// Returns the number of bytes for the initializer of the global
/// address.
SizeT getNumBytes() const {
SizeT Count = 0;
for (Initializer *Init : Initializers) {
for (const std::unique_ptr<Initializer> &Init : *Initializers) {
Count += Init->getNumBytes();
}
return Count;
......@@ -269,8 +292,9 @@ public:
/// Adds Initializer to the list of initializers. Takes ownership of
/// the initializer.
void addInitializer(Initializer *Initializer) {
Initializers.push_back(Initializer);
void addInitializer(std::unique_ptr<Initializer> Initializer) {
Initializers->emplace_back(std::move(Initializer));
HasInitializer = true;
}
/// Prints out type for initializer associated with the declaration
......@@ -293,9 +317,12 @@ public:
void setSuppressMangling() { ForceSuppressMangling = true; }
void discardInitializers() { Initializers = nullptr; }
private:
// list of initializers for the declared variable.
InitializerListType Initializers;
std::unique_ptr<InitializerListType> Initializers;
bool HasInitializer;
// The alignment of the declared variable.
uint32_t Alignment;
// True if a declared (global) constant.
......@@ -306,6 +333,7 @@ private:
VariableDeclaration()
: GlobalDeclaration(VariableDeclarationKind,
llvm::GlobalValue::InternalLinkage),
Initializers(new InitializerListType), HasInitializer(false),
Alignment(0), IsConstant(false), ForceSuppressMangling(false) {}
};
......
......@@ -161,6 +161,9 @@ public:
void dumpDest(const Cfg *Func) const;
virtual bool isRedundantAssign() const { return false; }
// TODO(jpp): Insts should not have non-trivial destructors, but they
// currently do. This dtor is marked final as a multi-step refactor that
// will eventually fix this problem.
virtual ~Inst() = default;
protected:
......@@ -229,7 +232,6 @@ protected:
void emitIAS(const Cfg * /*Func*/) const override {
llvm_unreachable("emitIAS() called on a non-lowered instruction");
}
~InstHighLevel() override {}
};
// Alloca instruction. This captures the size in bytes as getSrc(0),
......@@ -254,7 +256,7 @@ public:
private:
InstAlloca(Cfg *Func, Operand *ByteCount, uint32_t AlignInBytes,
Variable *Dest);
~InstAlloca() override {}
const uint32_t AlignInBytes;
};
......@@ -289,7 +291,6 @@ public:
private:
InstArithmetic(Cfg *Func, OpKind Op, Variable *Dest, Operand *Source1,
Operand *Source2);
~InstArithmetic() override {}
const OpKind Op;
};
......@@ -315,7 +316,6 @@ public:
private:
InstAssign(Cfg *Func, Variable *Dest, Operand *Source);
~InstAssign() override {}
};
// Branch instruction. This represents both conditional and
......@@ -359,7 +359,6 @@ private:
InstBr(Cfg *Func, Operand *Source, CfgNode *TargetTrue, CfgNode *TargetFalse);
// Unconditional branch
InstBr(Cfg *Func, CfgNode *Target);
~InstBr() override {}
CfgNode *TargetFalse; // Doubles as unconditional branch target
CfgNode *TargetTrue; // nullptr if unconditional branch
......@@ -399,7 +398,6 @@ protected:
HasSideEffects = HasSideEff;
addSource(CallTarget);
}
~InstCall() override {}
private:
bool HasTailCall;
......@@ -432,7 +430,7 @@ public:
private:
InstCast(Cfg *Func, OpKind CastKind, Variable *Dest, Operand *Source);
~InstCast() override {}
const OpKind CastKind;
};
......@@ -457,7 +455,6 @@ public:
private:
InstExtractElement(Cfg *Func, Variable *Dest, Operand *Source1,
Operand *Source2);
~InstExtractElement() override {}
};
// Floating-point comparison instruction. The source operands are
......@@ -487,7 +484,7 @@ public:
private:
InstFcmp(Cfg *Func, FCond Condition, Variable *Dest, Operand *Source1,
Operand *Source2);
~InstFcmp() override {}
const FCond Condition;
};
......@@ -518,7 +515,7 @@ public:
private:
InstIcmp(Cfg *Func, ICond Condition, Variable *Dest, Operand *Source1,
Operand *Source2);
~InstIcmp() override {}
const ICond Condition;
};
......@@ -543,7 +540,6 @@ public:
private:
InstInsertElement(Cfg *Func, Variable *Dest, Operand *Source1,
Operand *Source2, Operand *Source3);
~InstInsertElement() override {}
};
// Call to an intrinsic function. The call target is captured as getSrc(0),
......@@ -572,7 +568,7 @@ private:
: InstCall(Func, NumArgs, Dest, CallTarget, false, Info.HasSideEffects,
Inst::IntrinsicCall),
Info(Info) {}
~InstIntrinsicCall() override {}
const Intrinsics::IntrinsicInfo Info;
};
......@@ -595,7 +591,6 @@ public:
private:
InstLoad(Cfg *Func, Variable *Dest, Operand *SourceAddr);
~InstLoad() override {}
};
// Phi instruction. For incoming edge I, the node is Labels[I] and
......@@ -624,7 +619,6 @@ private:
Func->deallocateArrayOf<CfgNode *>(Labels);
Inst::destroy(Func);
}
~InstPhi() override {}
// Labels[] duplicates the InEdges[] information in the enclosing
// CfgNode, but the Phi instruction is created before InEdges[]
......@@ -655,7 +649,6 @@ public:
private:
InstRet(Cfg *Func, Operand *RetValue);
~InstRet() override {}
};
// Select instruction. The condition, true, and false operands are captured.
......@@ -679,7 +672,6 @@ public:
private:
InstSelect(Cfg *Func, Variable *Dest, Operand *Condition, Operand *Source1,
Operand *Source2);
~InstSelect() override {}
};
// Store instruction. The address operand is captured, along with the
......@@ -705,7 +697,6 @@ public:
private:
InstStore(Cfg *Func, Operand *Data, Operand *Addr);
~InstStore() override {}
};
// Switch instruction. The single source operand is captured as
......@@ -745,7 +736,6 @@ private:
Func->deallocateArrayOf<CfgNode *>(Labels);
Inst::destroy(Func);
}
~InstSwitch() override {}
CfgNode *LabelDefault;
SizeT NumCases; // not including the default case
......@@ -772,7 +762,6 @@ public:
private:
explicit InstUnreachable(Cfg *Func);
~InstUnreachable() override {}
};
// BundleLock instruction. There are no operands. Contains an option
......@@ -799,7 +788,6 @@ public:
private:
Option BundleOption;
InstBundleLock(Cfg *Func, Option BundleOption);
~InstBundleLock() override {}
};
// BundleUnlock instruction. There are no operands.
......@@ -821,7 +809,6 @@ public:
private:
explicit InstBundleUnlock(Cfg *Func);
~InstBundleUnlock() override {}
};
// FakeDef instruction. This creates a fake definition of a variable,
......@@ -853,7 +840,6 @@ public:
private:
InstFakeDef(Cfg *Func, Variable *Dest, Variable *Src);
~InstFakeDef() override {}
};
// FakeUse instruction. This creates a fake use of a variable, to
......@@ -877,7 +863,6 @@ public:
private:
InstFakeUse(Cfg *Func, Variable *Src);
~InstFakeUse() override {}
};
// FakeKill instruction. This "kills" a set of variables by modeling
......@@ -907,7 +892,6 @@ public:
private:
InstFakeKill(Cfg *Func, const Inst *Linked);
~InstFakeKill() override {}
// This instruction is ignored if Linked->isDeleted() is true.
const Inst *Linked;
......@@ -930,7 +914,6 @@ protected:
: Inst(Func, Kind, MaxSrcs, Dest) {
assert(Kind >= Target);
}
~InstTarget() override {}
};
bool checkForRedundantAssign(const Variable *Dest, const Operand *Source);
......
......@@ -59,7 +59,6 @@ public:
protected:
OperandARM32(OperandKindARM32 Kind, Type Ty)
: Operand(static_cast<OperandKind>(Kind), Ty) {}
~OperandARM32() override {}
};
// OperandARM32Mem represents a memory operand in any of the various ARM32
......@@ -141,7 +140,7 @@ private:
ConstantInteger32 *ImmOffset, AddrMode Mode);
OperandARM32Mem(Cfg *Func, Type Ty, Variable *Base, Variable *Index,
ShiftKind ShiftOp, uint16_t ShiftAmt, AddrMode Mode);
~OperandARM32Mem() override {}
Variable *Base;
ConstantInteger32 *ImmOffset;
Variable *Index;
......@@ -167,7 +166,6 @@ public:
protected:
OperandARM32Flex(OperandKindARM32 Kind, Type Ty) : OperandARM32(Kind, Ty) {}
~OperandARM32Flex() override {}
};
// Rotated immediate variant.
......@@ -202,7 +200,6 @@ public:
private:
OperandARM32FlexImm(Cfg *Func, Type Ty, uint32_t Imm, uint32_t RotateAmt);
~OperandARM32FlexImm() override {}
uint32_t Imm;
uint32_t RotateAmt;
......@@ -238,7 +235,6 @@ public:
private:
OperandARM32FlexReg(Cfg *Func, Type Ty, Variable *Reg, ShiftKind ShiftOp,
Operand *ShiftAmt);
~OperandARM32FlexReg() override {}
Variable *Reg;
ShiftKind ShiftOp;
......@@ -296,7 +292,7 @@ public:
protected:
InstARM32(Cfg *Func, InstKindARM32 Kind, SizeT Maxsrcs, Variable *Dest)
: InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {}
~InstARM32() override {}
static bool isClassof(const Inst *Inst, InstKindARM32 MyKind) {
return Inst->getKind() == static_cast<InstKind>(MyKind);
}
......@@ -377,7 +373,7 @@ private:
: InstARM32Pred(Func, K, 1, Dest, Predicate) {
addSource(Src);
}
~InstARM32UnaryopGPR() override {}
static const char *Opcode;
};
......@@ -423,7 +419,7 @@ private:
addSource(Dest);
addSource(Src);
}
~InstARM32TwoAddrGPR() override {}
static const char *Opcode;
};
......@@ -465,7 +461,6 @@ private:
: InstARM32Pred(Func, K, 1, Dest, Predicate) {
addSource(Source);
}
~InstARM32Movlike() override {}
static const char *Opcode;
};
......@@ -516,7 +511,7 @@ private:
addSource(Src1);
addSource(Src2);
}
~InstARM32ThreeAddrGPR() override {}
static const char *Opcode;
bool SetFlags;
};
......@@ -602,7 +597,7 @@ public:
private:
InstARM32Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse,
CondARM32::Cond Predicate);
~InstARM32Br() override {}
const CfgNode *TargetTrue;
const CfgNode *TargetFalse;
};
......@@ -656,7 +651,6 @@ public:
private:
InstARM32Call(Cfg *Func, Variable *Dest, Operand *CallTarget);
~InstARM32Call() override {}
};
// Integer compare instruction.
......@@ -679,7 +673,6 @@ public:
private:
InstARM32Cmp(Cfg *Func, Variable *Src1, Operand *Src2,
CondARM32::Cond Predicate);
~InstARM32Cmp() override {}
};
// Load instruction.
......@@ -703,7 +696,6 @@ public:
private:
InstARM32Ldr(Cfg *Func, Variable *Dest, OperandARM32Mem *Mem,
CondARM32::Cond Predicate);
~InstARM32Ldr() override {}
};
// Multiply Accumulate: d := x * y + a
......@@ -728,7 +720,6 @@ public:
private:
InstARM32Mla(Cfg *Func, Variable *Dest, Variable *Src0, Variable *Src1,
Variable *Acc, CondARM32::Cond Predicate);
~InstARM32Mla() override {}
};
// Pop into a list of GPRs. Technically this can be predicated, but we don't
......@@ -749,7 +740,7 @@ public:
private:
InstARM32Pop(Cfg *Func, const VarList &Dests);
~InstARM32Pop() override {}
VarList Dests;
};
......@@ -771,7 +762,6 @@ public:
private:
InstARM32Push(Cfg *Func, const VarList &Srcs);
~InstARM32Push() override {}
};
// Ret pseudo-instruction. This is actually a "bx" instruction with
......@@ -800,7 +790,6 @@ public:
private:
InstARM32Ret(Cfg *Func, Variable *LR, Variable *Source);
~InstARM32Ret() override {}
};
// Store instruction. It's important for liveness that there is no Dest
......@@ -825,7 +814,6 @@ public:
private:
InstARM32Str(Cfg *Func, Variable *Value, OperandARM32Mem *Mem,
CondARM32::Cond Predicate);
~InstARM32Str() override {}
};
// Unsigned Multiply Long: d.lo, d.hi := x * y
......@@ -850,7 +838,7 @@ public:
private:
InstARM32Umull(Cfg *Func, Variable *DestLo, Variable *DestHi, Variable *Src0,
Variable *Src1, CondARM32::Cond Predicate);
~InstARM32Umull() override {}
Variable *DestHi;
};
......
......@@ -45,7 +45,6 @@ public:
protected:
OperandX8632(OperandKindX8632 Kind, Type Ty)
: Operand(static_cast<OperandKind>(Kind), Ty) {}
~OperandX8632() override {}
};
// OperandX8632Mem represents the m32 addressing mode, with optional
......@@ -93,7 +92,7 @@ public:
private:
OperandX8632Mem(Cfg *Func, Type Ty, Variable *Base, Constant *Offset,
Variable *Index, uint16_t Shift, SegmentRegisters SegmentReg);
~OperandX8632Mem() override {}
Variable *Base;
Constant *Offset;
Variable *Index;
......@@ -134,14 +133,13 @@ public:
private:
VariableSplit(Cfg *Func, Variable *Var, Portion Part)
: OperandX8632(kSplit, IceType_i32), Func(Func), Var(Var), Part(Part) {
: OperandX8632(kSplit, IceType_i32), Var(Var), Part(Part) {
assert(Var->getType() == IceType_f64);
Vars = Func->allocateArrayOf<Variable *>(1);
Vars[0] = Var;
NumVars = 1;
}
~VariableSplit() override { Func->deallocateArrayOf<Variable *>(Vars); }
Cfg *Func; // Held only for the destructor.
Variable *Var;
Portion Part;
};
......@@ -298,7 +296,7 @@ public:
protected:
InstX8632(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs, Variable *Dest)
: InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {}
~InstX8632() override {}
static bool isClassof(const Inst *Inst, InstKindX8632 MyKind) {
return Inst->getKind() == static_cast<InstKind>(MyKind);
}
......@@ -359,7 +357,6 @@ private:
InstArithmetic::OpKind Op;
InstX8632FakeRMW(Cfg *Func, Operand *Data, Operand *Addr,
InstArithmetic::OpKind Op, Variable *Beacon);
~InstX8632FakeRMW() override {}
};
// InstX8632Label represents an intra-block label that is the target
......@@ -418,7 +415,7 @@ public:
private:
InstX8632Label(Cfg *Func, TargetX8632 *Target);
~InstX8632Label() override {}
SizeT Number; // used for unique label generation.
};
......@@ -489,7 +486,7 @@ public:
private:
InstX8632Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse,
const InstX8632Label *Label, CondX86::BrCond Condition);
~InstX8632Br() override {}
CondX86::BrCond Condition;
const CfgNode *TargetTrue;
const CfgNode *TargetFalse;
......@@ -559,7 +556,6 @@ public:
private:
InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget);
~InstX8632Call() override {}
};
// Emit a one-operand (GPR) instruction.
......@@ -610,7 +606,7 @@ private:
: InstX8632(Func, K, 1, llvm::dyn_cast<Variable>(SrcDest)) {
addSource(SrcDest);
}
~InstX8632InplaceopGPR() override {}
static const char *Opcode;
static const X8632::AssemblerX8632::GPREmitterOneOp Emitter;
};
......@@ -674,7 +670,7 @@ private:
: InstX8632(Func, K, 1, Dest) {
addSource(Src);
}
~InstX8632UnaryopGPR() override {}
static const char *Opcode;
static const X8632::AssemblerX8632::GPREmitterRegOp Emitter;
};
......@@ -724,7 +720,7 @@ private:
: InstX8632(Func, K, 1, Dest) {
addSource(Src);
}
~InstX8632UnaryopXmm() override {}
static const char *Opcode;
static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter;
};
......@@ -769,7 +765,7 @@ private:
addSource(Dest);
addSource(Source);
}
~InstX8632BinopGPRShift() override {}
static const char *Opcode;
static const X8632::AssemblerX8632::GPREmitterShiftOp Emitter;
};
......@@ -813,7 +809,7 @@ private:
addSource(Dest);
addSource(Source);
}
~InstX8632BinopGPR() override {}
static const char *Opcode;
static const X8632::AssemblerX8632::GPREmitterRegOp Emitter;
};
......@@ -857,7 +853,6 @@ private:
addSource(DestSrc0);
addSource(Src1);
}
~InstX8632BinopRMW() override {}
static const char *Opcode;
static const X8632::AssemblerX8632::GPREmitterAddrOp Emitter;
};
......@@ -905,7 +900,7 @@ private:
addSource(Dest);
addSource(Source);
}
~InstX8632BinopXmm() override {}
static const char *Opcode;
static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter;
};
......@@ -958,7 +953,7 @@ private:
addSource(Dest);
addSource(Source);
}
~InstX8632BinopXmmShift() override {}
static const char *Opcode;
static const X8632::AssemblerX8632::XmmEmitterShiftOp Emitter;
};
......@@ -1005,7 +1000,7 @@ private:
addSource(Source1);
addSource(Source2);
}
~InstX8632Ternop() override {}
static const char *Opcode;
};
......@@ -1052,7 +1047,7 @@ private:
addSource(Source0);
addSource(Source1);
}
~InstX8632ThreeAddressop() override {}
static const char *Opcode;
};
......@@ -1090,7 +1085,6 @@ private:
: InstX8632(Func, K, 1, Dest) {
addSource(Source);
}
~InstX8632Movlike() override {}
static const char *Opcode;
};
......@@ -1187,7 +1181,6 @@ protected:
// with optimizations.
HasSideEffects = Locked;
}
~InstX8632Lockable() override {}
};
// Mul instruction - unsigned multiply.
......@@ -1209,7 +1202,6 @@ public:
private:
InstX8632Mul(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2);
~InstX8632Mul() override {}
};
// Shld instruction - shift across a pair of operands.
......@@ -1232,7 +1224,6 @@ public:
private:
InstX8632Shld(Cfg *Func, Variable *Dest, Variable *Source1,
Variable *Source2);
~InstX8632Shld() override {}
};
// Shrd instruction - shift across a pair of operands.
......@@ -1255,7 +1246,6 @@ public:
private:
InstX8632Shrd(Cfg *Func, Variable *Dest, Variable *Source1,
Variable *Source2);
~InstX8632Shrd() override {}
};
// Conditional move instruction.
......@@ -1278,7 +1268,6 @@ public:
private:
InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source,
CondX86::BrCond Cond);
~InstX8632Cmov() override {}
CondX86::BrCond Condition;
};
......@@ -1304,7 +1293,6 @@ public:
private:
InstX8632Cmpps(Cfg *Func, Variable *Dest, Operand *Source,
CondX86::CmppsCond Cond);
~InstX8632Cmpps() override {}
CondX86::CmppsCond Condition;
};
......@@ -1333,7 +1321,6 @@ public:
private:
InstX8632Cmpxchg(Cfg *Func, Operand *DestOrAddr, Variable *Eax,
Variable *Desired, bool Locked);
~InstX8632Cmpxchg() override {}
};
// Cmpxchg8b instruction - cmpxchg8b <m64> will compare if <m64>
......@@ -1362,7 +1349,6 @@ public:
private:
InstX8632Cmpxchg8b(Cfg *Func, OperandX8632Mem *Dest, Variable *Edx,
Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked);
~InstX8632Cmpxchg8b() override {}
};
// Cvt instruction - wrapper for cvtsX2sY where X and Y are in {s,d,i}
......@@ -1390,7 +1376,6 @@ public:
private:
CvtVariant Variant;
InstX8632Cvt(Cfg *Func, Variable *Dest, Operand *Source, CvtVariant Variant);
~InstX8632Cvt() override {}
};
// cmp - Integer compare instruction.
......@@ -1411,7 +1396,6 @@ public:
private:
InstX8632Icmp(Cfg *Func, Operand *Src1, Operand *Src2);
~InstX8632Icmp() override {}
};
// ucomiss/ucomisd - floating-point compare instruction.
......@@ -1432,7 +1416,6 @@ public:
private:
InstX8632Ucomiss(Cfg *Func, Operand *Src1, Operand *Src2);
~InstX8632Ucomiss() override {}
};
// UD2 instruction.
......@@ -1452,7 +1435,6 @@ public:
private:
explicit InstX8632UD2(Cfg *Func);
~InstX8632UD2() override {}
};
// Test instruction.
......@@ -1473,7 +1455,6 @@ public:
private:
InstX8632Test(Cfg *Func, Operand *Source1, Operand *Source2);
~InstX8632Test() override {}
};
// Mfence instruction.
......@@ -1493,7 +1474,6 @@ public:
private:
explicit InstX8632Mfence(Cfg *Func);
~InstX8632Mfence() override {}
};
// This is essentially a "mov" instruction with an OperandX8632Mem
......@@ -1516,7 +1496,6 @@ public:
private:
InstX8632Store(Cfg *Func, Operand *Value, OperandX8632 *Mem);
~InstX8632Store() override {}
};
// This is essentially a vector "mov" instruction with an OperandX8632Mem
......@@ -1541,7 +1520,6 @@ public:
private:
InstX8632StoreP(Cfg *Func, Variable *Value, OperandX8632Mem *Mem);
~InstX8632StoreP() override {}
};
class InstX8632StoreQ : public InstX8632 {
......@@ -1562,7 +1540,6 @@ public:
private:
InstX8632StoreQ(Cfg *Func, Variable *Value, OperandX8632Mem *Mem);
~InstX8632StoreQ() override {}
};
// Nop instructions of varying length
......@@ -1585,7 +1562,6 @@ public:
private:
InstX8632Nop(Cfg *Func, SizeT Length);
~InstX8632Nop() override {}
NopVariant Variant;
};
......@@ -1607,7 +1583,6 @@ public:
private:
InstX8632Fld(Cfg *Func, Operand *Src);
~InstX8632Fld() override {}
};
// Fstp - store x87 st(0) into memory and pop st(0).
......@@ -1627,7 +1602,6 @@ public:
private:
InstX8632Fstp(Cfg *Func, Variable *Dest);
~InstX8632Fstp() override {}
};
class InstX8632Pop : public InstX8632 {
......@@ -1646,7 +1620,6 @@ public:
private:
InstX8632Pop(Cfg *Func, Variable *Dest);
~InstX8632Pop() override {}
};
class InstX8632Push : public InstX8632 {
......@@ -1665,7 +1638,6 @@ public:
private:
InstX8632Push(Cfg *Func, Variable *Source);
~InstX8632Push() override {}
};
// Ret instruction. Currently only supports the "ret" version that
......@@ -1688,7 +1660,6 @@ public:
private:
InstX8632Ret(Cfg *Func, Variable *Source);
~InstX8632Ret() override {}
};
// Conditional set-byte instruction.
......@@ -1710,7 +1681,6 @@ public:
private:
InstX8632Setcc(Cfg *Func, Variable *Dest, CondX86::BrCond Cond);
~InstX8632Setcc() override {}
const CondX86::BrCond Condition;
};
......@@ -1740,7 +1710,6 @@ public:
private:
InstX8632Xadd(Cfg *Func, Operand *Dest, Variable *Source, bool Locked);
~InstX8632Xadd() override {}
};
// Exchange instruction. Exchanges the first operand (destination
......@@ -1766,7 +1735,6 @@ public:
private:
InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source);
~InstX8632Xchg() override {}
};
// Declare partial template specializations of emit() methods that
......
......@@ -79,8 +79,6 @@ public:
dump(nullptr, Str);
}
virtual ~Operand() = default;
protected:
Operand(OperandKind Kind, Type Ty) : Ty(Ty), Kind(Kind) {}
......@@ -134,7 +132,6 @@ protected:
Vars = nullptr;
NumVars = 0;
}
~Constant() override {}
// PoolEntryID is an integer that uniquely identifies the constant
// within its constant pool. It is used for building the constant
// pool in the object code and for referencing its entries.
......@@ -182,7 +179,6 @@ public:
private:
ConstantPrimitive(Type Ty, PrimType Value, uint32_t PoolEntryID)
: Constant(K, Ty, PoolEntryID), Value(Value) {}
~ConstantPrimitive() override {}
const PrimType Value;
};
......@@ -271,7 +267,6 @@ private:
bool SuppressMangling, uint32_t PoolEntryID)
: Constant(kConstRelocatable, Ty, PoolEntryID), Offset(Offset),
Name(Name), SuppressMangling(SuppressMangling) {}
~ConstantRelocatable() override {}
const RelocOffsetT Offset; // fixed offset to add
const IceString Name; // optional for debug/dump
bool SuppressMangling;
......@@ -308,7 +303,6 @@ public:
private:
ConstantUndef(Type Ty, uint32_t PoolEntryID)
: Constant(kConstUndef, Ty, PoolEntryID) {}
~ConstantUndef() override {}
};
// RegWeight is a wrapper for a uint32_t weight value, with a
......@@ -514,7 +508,6 @@ protected:
Vars[0] = this;
NumVars = 1;
}
~Variable() override {}
// Number is unique across all variables, and is used as a
// (bit)vector index for liveness analysis.
const SizeT Number;
......
......@@ -512,12 +512,12 @@ void TargetDataLowering::emitGlobal(const VariableDeclaration &Var,
Str << MangledName << ":\n";
if (HasNonzeroInitializer) {
for (VariableDeclaration::Initializer *Init : Var.getInitializers()) {
for (const std::unique_ptr<VariableDeclaration::Initializer> &Init :
Var.getInitializers()) {
switch (Init->getKind()) {
case VariableDeclaration::Initializer::DataInitializerKind: {
const auto &Data =
llvm::cast<VariableDeclaration::DataInitializer>(Init)
->getContents();
const auto &Data = llvm::cast<VariableDeclaration::DataInitializer>(
Init.get())->getContents();
for (SizeT i = 0; i < Init->getNumBytes(); ++i) {
Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n";
}
......@@ -528,7 +528,7 @@ void TargetDataLowering::emitGlobal(const VariableDeclaration &Var,
break;
case VariableDeclaration::Initializer::RelocInitializerKind: {
const auto *Reloc =
llvm::cast<VariableDeclaration::RelocInitializer>(Init);
llvm::cast<VariableDeclaration::RelocInitializer>(Init.get());
Str << "\t" << getEmit32Directive() << "\t";
Str << Reloc->getDeclaration()->mangleName(Ctx);
if (RelocOffsetT Offset = Reloc->getOffset()) {
......
......@@ -293,7 +293,8 @@ public:
assert(VariableDeclarations);
assert(VariableDeclarations->empty());
for (size_t i = 0; i < Count; ++i) {
VariableDeclarations->push_back(Ice::VariableDeclaration::create());
VariableDeclarations->push_back(
Ice::VariableDeclaration::create(getTranslator().getContext()));
}
}
......@@ -904,7 +905,8 @@ public:
GlobalsParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
: BlockParserBaseClass(BlockID, EnclosingParser),
Timer(Ice::TimerStack::TT_parseGlobals, getTranslator().getContext()),
DummyGlobalVar(Ice::VariableDeclaration::create()),
DummyGlobalVar(
Ice::VariableDeclaration::create(getTranslator().getContext())),
CurGlobalVar(DummyGlobalVar) {}
~GlobalsParser() final {}
......@@ -1017,7 +1019,7 @@ void GlobalsParser::ProcessRecord() {
if (isIRGenerationDisabled())
return;
CurGlobalVar->addInitializer(
new Ice::VariableDeclaration::ZeroInitializer(Values[0]));
Ice::VariableDeclaration::ZeroInitializer::create(Values[0]));
return;
}
case naclbitc::GLOBALVAR_DATA: {
......@@ -1027,7 +1029,7 @@ void GlobalsParser::ProcessRecord() {
if (isIRGenerationDisabled())
return;
CurGlobalVar->addInitializer(
new Ice::VariableDeclaration::DataInitializer(Values));
Ice::VariableDeclaration::DataInitializer::create(Values));
return;
}
case naclbitc::GLOBALVAR_RELOC: {
......@@ -1040,8 +1042,9 @@ void GlobalsParser::ProcessRecord() {
Ice::SizeT Offset = 0;
if (Values.size() == 2)
Offset = Values[1];
CurGlobalVar->addInitializer(new Ice::VariableDeclaration::RelocInitializer(
Context->getGlobalDeclarationByID(Index), Offset));
CurGlobalVar->addInitializer(
Ice::VariableDeclaration::RelocInitializer::create(
Context->getGlobalDeclarationByID(Index), Offset));
return;
}
default:
......@@ -2945,7 +2948,8 @@ void ModuleParser::ProcessRecord() {
}
bool IsProto = Values[2] == 1;
Ice::FunctionDeclaration *Func = Ice::FunctionDeclaration::create(
Signature, CallingConv, Linkage, IsProto);
Context->getTranslator().getContext(), Signature, CallingConv, Linkage,
IsProto);
Context->setNextFunctionID(Func);
return;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment