Chromium Code Reviews| Index: src/IceOperand.h |
| diff --git a/src/IceOperand.h b/src/IceOperand.h |
| index bc48b74da0639623550479d341a400dc5ec01dde..648d4635ed788c6d18b8eb6d49152b265a51cb07 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,14 @@ 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; } |
| + void initShouldBePooled(); |
|
John
2016/03/29 14:23:16
maybe explain this?
should this be private?
Should
Jim Stichnoth
2016/03/29 21:40:49
Done.
|
| bool getShouldBePooled() const { return ShouldBePooled; } |
| // This should be thread-safe because the constant pool lock is acquired |
| @@ -161,8 +157,10 @@ protected: |
| Vars = nullptr; |
| NumVars = 0; |
| } |
| + 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 +179,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 +233,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(); |
| + LabelName = GlobalString(Ctx, Str.str()); |
| } |
| - static bool classof(const Operand *Operand) { |
| - return Operand->getKind() == K; |
| - } |
| - |
| - virtual bool shouldBeRandomizedOrPooled(const GlobalContext *Ctx) override { |
| - (void)Ctx; |
| - return false; |
| - } |
| - |
| -private: |
| - ConstantPrimitive(Type Ty, PrimType Value) : Constant(K, Ty), Value(Value) {} |
| const PrimType Value; |
| }; |
| @@ -251,8 +255,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 +318,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 +331,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); |
| @@ -349,6 +352,12 @@ public: |
| ConstantRelocatable(Ty, Tuple.Offset, Tuple.OffsetExpr, Tuple.Name, |
| Tuple.EmitString); |
| } |
| +#if 0 |
|
John
2016/03/29 14:23:16
remove if 0
Jim Stichnoth
2016/03/29 21:40:49
Done.
|
| + static ConstantRelocatable *create(GlobalContext *Ctx, Type Ty, |
| + const RelocatableTuple &Tuple) { |
| + return create(Ctx, Ty, Tuple); |
| + } |
| +#endif |
| RelocOffsetT getOffset() const { |
| RelocOffsetT Ret = Offset; |
| @@ -358,9 +367,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 +384,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 +646,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(Func, NewName); |
| } |
| bool getIsArg() const { return IsArgument; } |
| @@ -661,7 +671,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 +735,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 +750,22 @@ public: |
| } |
| protected: |
| - Variable(OperandKind K, Type Ty, SizeT Index) |
| - : Operand(K, Ty), Number(Index), |
| + Variable(const Cfg *Func, OperandKind K, Type Ty, SizeT Index) |
| + : Operand(K, Ty), Number(Index), Name(Func), |
| RegisterClass(static_cast<RegClass>(Ty)) { |
| Vars = VarsReal; |
| Vars[0] = this; |
| NumVars = 1; |
| + if (BuildDefs::dump()) { |
| + Name = VariableString(Func, "__" + std::to_string(getIndex())); |
| + } else { |
| + Name = VariableString(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 +799,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 +834,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 +846,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); |
| } |