| Index: src/IceOperand.h
|
| diff --git a/src/IceOperand.h b/src/IceOperand.h
|
| index bc48b74da0639623550479d341a400dc5ec01dde..327c348f6fb99a1f2d8c72d6f3137a55a5650073 100644
|
| --- a/src/IceOperand.h
|
| +++ b/src/IceOperand.h
|
| @@ -22,6 +22,7 @@
|
| #include "IceDefs.h"
|
| #include "IceCfg.h"
|
| #include "IceGlobalContext.h"
|
| +#include "IceStringPool.h"
|
| #include "IceTypes.h"
|
|
|
| #include "llvm/Support/Format.h"
|
| @@ -121,10 +122,6 @@ class Constant : public Operand {
|
| Constant &operator=(const Constant &) = delete;
|
|
|
| public:
|
| - virtual void emitPoolLabel(Ostream &Str) const {
|
| - (void)Str;
|
| - llvm::report_fatal_error("emitPoolLabel not defined for type");
|
| - };
|
| // Declare the lookup counter to take minimal space in a non-DUMP build.
|
| using CounterType =
|
| std::conditional<BuildDefs::dump(), uint64_t, uint8_t>::type;
|
| @@ -136,15 +133,13 @@ public:
|
| return Kind >= kConst_Base && Kind <= kConst_Max;
|
| }
|
|
|
| + const GlobalString getLabelName() const { return LabelName; }
|
| +
|
| /// Judge if this given immediate should be randomized or pooled By default
|
| /// should return false, only constant integers should truly go through this
|
| /// method.
|
| - virtual bool shouldBeRandomizedOrPooled(const GlobalContext *Ctx) {
|
| - (void)Ctx;
|
| - return false;
|
| - }
|
| + virtual bool shouldBeRandomizedOrPooled() const { return false; }
|
|
|
| - void setShouldBePooled(bool R) { ShouldBePooled = R; }
|
| bool getShouldBePooled() const { return ShouldBePooled; }
|
|
|
| // This should be thread-safe because the constant pool lock is acquired
|
| @@ -161,8 +156,13 @@ protected:
|
| Vars = nullptr;
|
| NumVars = 0;
|
| }
|
| + /// Set the ShouldBePooled field to the proper value after the object is fully
|
| + /// initialized.
|
| + void initShouldBePooled();
|
| + GlobalString LabelName;
|
| /// Whether we should pool this constant. Usually Float/Double and pooled
|
| - /// Integers should be flagged true.
|
| + /// Integers should be flagged true. Ideally this field would be const, but
|
| + /// it needs to be initialized only after the subclass is fully constructed.
|
| bool ShouldBePooled = false;
|
| /// Note: If ShouldBePooled is ever removed from the base class, we will want
|
| /// to completely disable LookupCount in a non-DUMP build to save space.
|
| @@ -181,11 +181,34 @@ public:
|
|
|
| static ConstantPrimitive *create(GlobalContext *Ctx, Type Ty,
|
| PrimType Value) {
|
| - return new (Ctx->allocate<ConstantPrimitive>())
|
| - ConstantPrimitive(Ty, Value);
|
| + auto *Const =
|
| + new (Ctx->allocate<ConstantPrimitive>()) ConstantPrimitive(Ty, Value);
|
| + Const->initShouldBePooled();
|
| + if (Const->getShouldBePooled())
|
| + Const->initName(Ctx);
|
| + return Const;
|
| }
|
| PrimType getValue() const { return Value; }
|
| - void emitPoolLabel(Ostream &Str) const final {
|
| + using Constant::emit;
|
| + void emit(TargetLowering *Target) const final;
|
| + using Constant::dump;
|
| + void dump(const Cfg *, Ostream &Str) const override {
|
| + if (BuildDefs::dump())
|
| + Str << getValue();
|
| + }
|
| +
|
| + static bool classof(const Operand *Operand) {
|
| + return Operand->getKind() == K;
|
| + }
|
| +
|
| + virtual bool shouldBeRandomizedOrPooled() const override { return false; }
|
| +
|
| +private:
|
| + ConstantPrimitive(Type Ty, PrimType Value) : Constant(K, Ty), Value(Value) {}
|
| +
|
| + void initName(GlobalContext *Ctx) {
|
| + std::string Buffer;
|
| + llvm::raw_string_ostream Str(Buffer);
|
| Str << ".L$" << getType() << "$";
|
| // Print hex characters byte by byte, starting from the most significant
|
| // byte. NOTE: This ordering assumes Subzero runs on a little-endian
|
| @@ -212,26 +235,9 @@ public:
|
| }
|
| Str << Buf;
|
| }
|
| - }
|
| - using Constant::emit;
|
| - void emit(TargetLowering *Target) const final;
|
| - using Constant::dump;
|
| - void dump(const Cfg *, Ostream &Str) const override {
|
| - if (BuildDefs::dump())
|
| - Str << getValue();
|
| - }
|
| -
|
| - static bool classof(const Operand *Operand) {
|
| - return Operand->getKind() == K;
|
| - }
|
| -
|
| - virtual bool shouldBeRandomizedOrPooled(const GlobalContext *Ctx) override {
|
| - (void)Ctx;
|
| - return false;
|
| + LabelName = GlobalString::createWithString(Ctx, Str.str());
|
| }
|
|
|
| -private:
|
| - ConstantPrimitive(Type Ty, PrimType Value) : Constant(K, Ty), Value(Value) {}
|
| const PrimType Value;
|
| };
|
|
|
| @@ -251,8 +257,7 @@ inline void ConstantInteger32::dump(const Cfg *, Ostream &Str) const {
|
| }
|
|
|
| /// Specialization of the template member function for ConstantInteger32
|
| -template <>
|
| -bool ConstantInteger32::shouldBeRandomizedOrPooled(const GlobalContext *Ctx);
|
| +template <> bool ConstantInteger32::shouldBeRandomizedOrPooled() const;
|
|
|
| template <>
|
| inline void ConstantInteger64::dump(const Cfg *, Ostream &Str) const {
|
| @@ -315,12 +320,12 @@ class RelocatableTuple {
|
|
|
| public:
|
| RelocatableTuple(const RelocOffsetT Offset,
|
| - const RelocOffsetArray &OffsetExpr, const IceString &Name)
|
| + const RelocOffsetArray &OffsetExpr, GlobalString Name)
|
| : Offset(Offset), OffsetExpr(OffsetExpr), Name(Name) {}
|
|
|
| RelocatableTuple(const RelocOffsetT Offset,
|
| - const RelocOffsetArray &OffsetExpr, const IceString &Name,
|
| - const IceString &EmitString)
|
| + const RelocOffsetArray &OffsetExpr, GlobalString Name,
|
| + const std::string &EmitString)
|
| : Offset(Offset), OffsetExpr(OffsetExpr), Name(Name),
|
| EmitString(EmitString) {}
|
|
|
| @@ -328,8 +333,8 @@ public:
|
|
|
| const RelocOffsetT Offset;
|
| const RelocOffsetArray OffsetExpr;
|
| - const IceString Name;
|
| - const IceString EmitString;
|
| + const GlobalString Name;
|
| + const std::string EmitString;
|
| };
|
|
|
| bool operator==(const RelocatableTuple &A, const RelocatableTuple &B);
|
| @@ -358,9 +363,9 @@ public:
|
| return Ret;
|
| }
|
|
|
| - const IceString &getEmitString() const { return EmitString; }
|
| + const std::string &getEmitString() const { return EmitString; }
|
|
|
| - const IceString &getName() const { return Name; }
|
| + GlobalString getName() const { return Name; }
|
| using Constant::emit;
|
| void emit(TargetLowering *Target) const final;
|
| void emitWithoutPrefix(const TargetLowering *Target,
|
| @@ -375,15 +380,15 @@ public:
|
|
|
| private:
|
| ConstantRelocatable(Type Ty, const RelocOffsetT Offset,
|
| - const RelocOffsetArray &OffsetExpr, const IceString &Name,
|
| - const IceString &EmitString)
|
| + const RelocOffsetArray &OffsetExpr, GlobalString Name,
|
| + const std::string &EmitString)
|
| : Constant(kConstRelocatable, Ty), Offset(Offset), OffsetExpr(OffsetExpr),
|
| Name(Name), EmitString(EmitString) {}
|
|
|
| const RelocOffsetT Offset; /// fixed, known offset to add
|
| const RelocOffsetArray OffsetExpr; /// fixed, unknown offset to add
|
| - const IceString Name; /// optional for debug/dump
|
| - const IceString EmitString; /// optional for textual emission
|
| + const GlobalString Name; /// optional for debug/dump
|
| + const std::string EmitString; /// optional for textual emission
|
| };
|
|
|
| /// ConstantUndef represents an unspecified bit pattern. Although it is legal to
|
| @@ -637,16 +642,17 @@ class Variable : public Operand {
|
|
|
| public:
|
| static Variable *create(Cfg *Func, Type Ty, SizeT Index) {
|
| - return new (Func->allocate<Variable>()) Variable(kVariable, Ty, Index);
|
| + return new (Func->allocate<Variable>())
|
| + Variable(Func, kVariable, Ty, Index);
|
| }
|
|
|
| SizeT getIndex() const { return Number; }
|
| - IceString getName(const Cfg *Func) const;
|
| - virtual void setName(Cfg *Func, const IceString &NewName) {
|
| - // Make sure that the name can only be set once.
|
| - assert(NameIndex == Cfg::IdentifierIndexInvalid);
|
| - if (!NewName.empty())
|
| - NameIndex = Func->addIdentifierName(NewName);
|
| + std::string getName(const Cfg *Func) const;
|
| + virtual void setName(const Cfg *Func, const std::string &NewName) {
|
| + (void)Func;
|
| + if (NewName.empty())
|
| + return;
|
| + Name = VariableString::createWithString(Func, NewName);
|
| }
|
|
|
| bool getIsArg() const { return IsArgument; }
|
| @@ -661,7 +667,7 @@ public:
|
| void setStackOffset(int32_t Offset) { StackOffset = Offset; }
|
| /// Returns the variable's stack offset in symbolic form, to improve
|
| /// readability in DecorateAsm mode.
|
| - IceString getSymbolicStackOffset(const Cfg *Func) const {
|
| + std::string getSymbolicStackOffset(const Cfg *Func) const {
|
| if (!BuildDefs::dump())
|
| return "";
|
| return "lv$" + getName(Func);
|
| @@ -725,7 +731,7 @@ public:
|
| /// IsImplicitArgument, IgnoreLiveness, RegNumTmp, Live, LoVar, HiVar,
|
| /// VarsReal. If NewRegNum.hasValue(), then that register assignment is made
|
| /// instead of copying the existing assignment.
|
| - const Variable *asType(Type Ty, RegNumT NewRegNum) const;
|
| + const Variable *asType(const Cfg *Func, Type Ty, RegNumT NewRegNum) const;
|
|
|
| void emit(const Cfg *Func) const override;
|
| using Operand::dump;
|
| @@ -740,17 +746,24 @@ public:
|
| }
|
|
|
| protected:
|
| - Variable(OperandKind K, Type Ty, SizeT Index)
|
| + Variable(const Cfg *Func, OperandKind K, Type Ty, SizeT Index)
|
| : Operand(K, Ty), Number(Index),
|
| + Name(VariableString::createWithoutString(Func)),
|
| RegisterClass(static_cast<RegClass>(Ty)) {
|
| Vars = VarsReal;
|
| Vars[0] = this;
|
| NumVars = 1;
|
| + if (BuildDefs::dump()) {
|
| + Name = VariableString::createWithString(
|
| + Func, "__" + std::to_string(getIndex()));
|
| + } else {
|
| + Name = VariableString::createWithoutString(Func);
|
| + }
|
| }
|
| /// Number is unique across all variables, and is used as a (bit)vector index
|
| /// for liveness analysis.
|
| const SizeT Number;
|
| - Cfg::IdentifierIndexType NameIndex = Cfg::IdentifierIndexInvalid;
|
| + VariableString Name;
|
| bool IsArgument = false;
|
| bool IsImplicitArgument = false;
|
| /// IgnoreLiveness means that the variable should be ignored when constructing
|
| @@ -784,10 +797,10 @@ class Variable64On32 : public Variable {
|
| public:
|
| static Variable64On32 *create(Cfg *Func, Type Ty, SizeT Index) {
|
| return new (Func->allocate<Variable64On32>())
|
| - Variable64On32(kVariable64On32, Ty, Index);
|
| + Variable64On32(Func, kVariable64On32, Ty, Index);
|
| }
|
|
|
| - void setName(Cfg *Func, const IceString &NewName) override {
|
| + void setName(const Cfg *Func, const std::string &NewName) override {
|
| Variable::setName(Func, NewName);
|
| if (LoVar && HiVar) {
|
| LoVar->setName(Func, getName(Func) + "__lo");
|
| @@ -819,8 +832,10 @@ public:
|
| HiVar = Func->makeVariable(IceType_i32);
|
| LoVar->setIsArg(getIsArg());
|
| HiVar->setIsArg(getIsArg());
|
| - LoVar->setName(Func, getName(Func) + "__lo");
|
| - HiVar->setName(Func, getName(Func) + "__hi");
|
| + if (BuildDefs::dump()) {
|
| + LoVar->setName(Func, getName(Func) + "__lo");
|
| + HiVar->setName(Func, getName(Func) + "__hi");
|
| + }
|
| }
|
|
|
| static bool classof(const Operand *Operand) {
|
| @@ -829,7 +844,8 @@ public:
|
| }
|
|
|
| protected:
|
| - Variable64On32(OperandKind K, Type Ty, SizeT Index) : Variable(K, Ty, Index) {
|
| + Variable64On32(const Cfg *Func, OperandKind K, Type Ty, SizeT Index)
|
| + : Variable(Func, K, Ty, Index) {
|
| assert(typeWidthInBytes(Ty) == 8);
|
| }
|
|
|
|
|