Index: src/IceTargetLoweringMIPS32.h |
diff --git a/src/IceTargetLoweringMIPS32.h b/src/IceTargetLoweringMIPS32.h |
index 5802052ce2082bfb4334d77f98a9b95460fe5393..03651ad08a6824982cfd1b30cab912aa6d4bb32b 100644 |
--- a/src/IceTargetLoweringMIPS32.h |
+++ b/src/IceTargetLoweringMIPS32.h |
@@ -46,6 +46,12 @@ public: |
return makeUnique<MIPS32::AssemblerMIPS32>(); |
} |
+ void initNodeForLowering(CfgNode *Node) override { |
+ Computations.forgetProducers(); |
+ Computations.recordProducers(Node); |
+ Computations.dump(Func); |
+ } |
+ |
void translateOm1() override; |
void translateO2() override; |
bool doBranchOpt(Inst *Instr, const CfgNode *NextNode) override; |
@@ -152,6 +158,12 @@ public: |
void _br(CfgNode *Target) { Context.insert<InstMIPS32Br>(Target); } |
+ void _br(CfgNode *TargetTrue, CfgNode *TargetFalse, Operand *Src0, |
+ Operand *Src1, CondMIPS32::Cond Condition) { |
+ Context.insert<InstMIPS32Br>(TargetTrue, TargetFalse, Src0, Src1, |
+ Condition); |
+ } |
+ |
void _ret(Variable *RA, Variable *Src0 = nullptr) { |
Context.insert<InstMIPS32Ret>(RA, Src0); |
} |
@@ -349,6 +361,66 @@ protected: |
private: |
ENABLE_MAKE_UNIQUE; |
+ |
+ class ComputationTracker { |
+ public: |
+ ComputationTracker() = default; |
+ ~ComputationTracker() = default; |
+ |
+ void forgetProducers() { KnownComputations.clear(); } |
+ void recordProducers(CfgNode *Node); |
+ |
+ const Inst *getProducerOf(const Operand *Opnd) const { |
+ auto *Var = llvm::dyn_cast<Variable>(Opnd); |
+ if (Var == nullptr) { |
+ return nullptr; |
+ } |
+ |
+ auto Iter = KnownComputations.find(Var->getIndex()); |
+ if (Iter == KnownComputations.end()) { |
+ return nullptr; |
+ } |
+ |
+ return Iter->second.Instr; |
+ } |
+ |
+ void dump(const Cfg *Func) const { |
+ if (!BuildDefs::dump() || !Func->isVerbose(IceV_Folding)) |
+ return; |
+ OstreamLocker L(Func->getContext()); |
+ Ostream &Str = Func->getContext()->getStrDump(); |
+ Str << "foldable producer:\n"; |
+ for (const auto &Computation : KnownComputations) { |
+ Str << " "; |
+ Computation.second.Instr->dump(Func); |
+ Str << "\n"; |
+ } |
+ Str << "\n"; |
+ } |
+ |
+ private: |
+ class ComputationEntry { |
+ public: |
+ ComputationEntry(Inst *I, Type Ty) : Instr(I), ComputationType(Ty) {} |
+ Inst *const Instr; |
+ // Boolean folding is disabled for variables whose live range is multi |
+ // block. We conservatively initialize IsLiveOut to true, and set it to |
+ // false once we find the end of the live range for the variable defined |
+ // by this instruction. If liveness analysis is not performed (e.g., in |
+ // Om1 mode) IsLiveOut will never be set to false, and folding will be |
+ // disabled. |
+ bool IsLiveOut = true; |
+ int32_t NumUses = 0; |
+ Type ComputationType; |
+ }; |
+ |
+ // ComputationMap maps a Variable number to a payload identifying which |
+ // instruction defined it. |
+ using ComputationMap = CfgUnorderedMap<SizeT, ComputationEntry>; |
+ ComputationMap KnownComputations; |
+ }; |
+ |
+ ComputationTracker Computations; |
}; |
class TargetDataMIPS32 final : public TargetDataLowering { |