Chromium Code Reviews| Index: src/IceTargetLoweringX8632.h |
| diff --git a/src/IceTargetLoweringX8632.h b/src/IceTargetLoweringX8632.h |
| index f114dba2fbdb9abedd171557f7fe6184a043cb5e..79557ae52b8b6f1c8c5f2b2c1db5516af20e9b88 100644 |
| --- a/src/IceTargetLoweringX8632.h |
| +++ b/src/IceTargetLoweringX8632.h |
| @@ -16,14 +16,81 @@ |
| #ifndef SUBZERO_SRC_ICETARGETLOWERINGX8632_H |
| #define SUBZERO_SRC_ICETARGETLOWERINGX8632_H |
| +#include <unordered_map> |
| + |
| #include "assembler_ia32.h" |
| #include "IceDefs.h" |
| +#include "IceInst.h" |
| #include "IceInstX8632.h" |
| #include "IceRegistersX8632.h" |
| #include "IceTargetLowering.h" |
| namespace Ice { |
| +class BoolFoldingEntry { |
| + BoolFoldingEntry(const BoolFoldingEntry &) = delete; |
| + |
| +public: |
| + BoolFoldingEntry() |
| + : Instr(nullptr), IsComplex(false), IsLiveOut(true), NumUses(0) {} |
| + explicit BoolFoldingEntry(Inst *I); |
| + BoolFoldingEntry &operator=(const BoolFoldingEntry &) = default; |
| + // Instr is the instruction producing the i1-type variable of interest. |
| + Inst *Instr; |
| + // IsComplex is the cached result of BoolFolding::hasComplexLowering(Instr). |
| + bool IsComplex; |
| + // IsLiveOut is initialized conservatively to true, and is set to false when |
| + // we encounter an instruction that ends Var's live range. We disable the |
| + // folding optimization when Var is live beyond this basic block. Note that |
| + // if liveness analysis is not performed (e.g. in Om1 mode), IsLiveOut will |
| + // always be true and the folding optimization will never be performed. |
| + bool IsLiveOut; |
| + // NumUses counts the number of times Var is used as a source operand in the |
| + // basic block. If IsComplex is true and there is more than one use of Var, |
| + // then the folding optimization is disabled for Var. |
| + uint32_t NumUses; |
| +}; |
| + |
| +class BoolFolding { |
| +public: |
| + enum BoolFoldingProducerKind { |
| + PK_None, |
| + PK_Icmp32, |
| + PK_Icmp64, |
| + PK_Fcmp, |
| + PK_Trunc |
| + }; |
| + |
| + // Currently the actual enum values are not used (other than CK_None), but we |
| + // go |
| + // ahead and produce them anyway for symmetry with the |
| + // BoolFoldingProducerKind. |
| + enum BoolFoldingConsumerKind { CK_None, CK_Br, CK_Select, CK_Sext, CK_Zext }; |
|
jvoung (off chromium)
2015/05/17 16:38:16
Just some random thoughts as I was catching up on
|
| + |
| +private: |
| + BoolFolding(const BoolFolding &) = delete; |
| + BoolFolding &operator=(const BoolFolding &) = delete; |
| + |
| +public: |
| + BoolFolding() {} |
| + static BoolFoldingProducerKind getProducerKind(const Inst *Instr); |
| + static BoolFoldingConsumerKind getConsumerKind(const Inst *Instr); |
| + static bool hasComplexLowering(const Inst *Instr); |
| + void init(CfgNode *Node); |
| + const Inst *getProducerFor(const Operand *Opnd) const; |
| + void dump(const Cfg *Func) const; |
| + |
| +private: |
| + // Returns true if Producers contains a valid entry for the given VarNum. |
| + bool containsValid(SizeT VarNum) const { |
| + auto Element = Producers.find(VarNum); |
| + return Element != Producers.end() && Element->second.Instr != nullptr; |
| + } |
| + void setInvalid(SizeT VarNum) { Producers[VarNum].Instr = nullptr; } |
| + // Producers maps Variable::Number to a BoolFoldingEntry. |
| + std::unordered_map<SizeT, BoolFoldingEntry> Producers; |
| +}; |
| + |
| class TargetX8632 : public TargetLowering { |
| TargetX8632() = delete; |
| TargetX8632(const TargetX8632 &) = delete; |
| @@ -63,6 +130,7 @@ public: |
| void emit(const ConstantDouble *C) const final; |
| void lowerArguments() override; |
| + void initNodeForLowering(CfgNode *Node) override; |
| void addProlog(CfgNode *Node) override; |
| void addEpilog(CfgNode *Node) override; |
| // Ensure that a 64-bit Variable has been split into 2 32-bit |
| @@ -157,6 +225,8 @@ protected: |
| Operand *legalize(Operand *From, LegalMask Allowed = Legal_All, |
| int32_t RegNum = Variable::NoRegister); |
| Variable *legalizeToVar(Operand *From, int32_t RegNum = Variable::NoRegister); |
| + // Legalize the first source operand for use in the cmp instruction. |
| + Operand *legalizeSrc0ForCmp(Operand *Src0, Operand *Src1); |
| // Turn a pointer operand into a memory operand that can be |
| // used by a real load/store operation. Legalizes the operand as well. |
| // This is a nop if the operand is already a legal memory operand. |
| @@ -507,6 +577,7 @@ protected: |
| private: |
| ~TargetX8632() override {} |
| + BoolFolding FoldingInfo; |
| }; |
| class TargetDataX8632 : public TargetDataLowering { |