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 { |