Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2209)

Unified Diff: src/IceTargetLoweringMIPS32.cpp

Issue 1993773004: [Subzero][MIPS32] Addition of bool folding machinery and implementation of conditional branches (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Added tests for eq and ne branches and corrected branch target label emission Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/IceTargetLoweringMIPS32.cpp
diff --git a/src/IceTargetLoweringMIPS32.cpp b/src/IceTargetLoweringMIPS32.cpp
index cbfad693619260aa00cd2b05f75316550c1e97d7..46718f6fe0b57d0156d277c4aa79e7f1fcf35e71 100644
--- a/src/IceTargetLoweringMIPS32.cpp
+++ b/src/IceTargetLoweringMIPS32.cpp
@@ -22,6 +22,7 @@
#include "IceELFObjectWriter.h"
#include "IceGlobalInits.h"
#include "IceInstMIPS32.h"
+#include "IceInstVarIter.h"
#include "IceLiveness.h"
#include "IceOperand.h"
#include "IcePhiLoweringImpl.h"
@@ -813,7 +814,78 @@ void TargetMIPS32::lowerBr(const InstBr *Instr) {
_br(Instr->getTargetUnconditional());
return;
}
- UnimplementedLoweringError(this, Instr);
+ CfgNode *TargetTrue = Instr->getTargetTrue();
+ CfgNode *TargetFalse = Instr->getTargetFalse();
+ Operand *Boolean = Instr->getCondition();
+ const Inst *Producer = Computations.getProducerOf(Boolean);
+ assert(Producer != nullptr);
+ if (Producer->getKind() == Inst::Icmp) {
+ const InstIcmp *CompareInst = llvm::cast<InstIcmp>(Producer);
+ Operand *Src0 = CompareInst->getSrc(0);
+ Operand *Src1 = CompareInst->getSrc(1);
+ const Type Src0Ty = Src0->getType();
+ const Type Src1Ty = Src1->getType();
+ if (Src0Ty == IceType_i64 || Src1Ty == IceType_i64) {
Jim Stichnoth 2016/05/19 15:03:41 Instead of testing both types against i64, I sugge
sagar.thakur 2016/05/23 18:30:26 Done.
+ UnimplementedLoweringError(this, Instr);
+ return;
+ }
+ auto *Src0R = legalizeToReg(Src0);
+ auto *Src1R = legalizeToReg(Src1);
+ auto *DestT = makeReg(Src0Ty);
+ switch (CompareInst->getCondition()) {
+ default:
+ break;
+ case InstIcmp::Eq: {
+ _br(TargetTrue, TargetFalse, Src0R, Src1R, CondMIPS32::Cond::NE);
+ break;
+ }
+ case InstIcmp::Ne: {
+ _br(TargetTrue, TargetFalse, Src0R, Src1R, CondMIPS32::Cond::EQ);
+ break;
+ }
+ case InstIcmp::Ugt: {
+ _sltu(DestT, Src1R, Src0R);
+ _br(TargetTrue, TargetFalse, DestT, NULL, CondMIPS32::Cond::EQZ);
Jim Stichnoth 2016/05/19 15:03:41 All the NULL should be nullptr.
sagar.thakur 2016/05/23 18:30:26 Done.
+ break;
+ }
+ case InstIcmp::Uge: {
+ _sltu(DestT, Src0R, Src1R);
+ _br(TargetTrue, TargetFalse, DestT, NULL, CondMIPS32::Cond::NEZ);
+ break;
+ }
+ case InstIcmp::Ult: {
+ _sltu(DestT, Src0R, Src1R);
+ _br(TargetTrue, TargetFalse, DestT, NULL, CondMIPS32::Cond::EQZ);
+ break;
+ }
+ case InstIcmp::Ule: {
+ _sltu(DestT, Src1R, Src0R);
+ _br(TargetTrue, TargetFalse, DestT, NULL, CondMIPS32::Cond::NEZ);
+ break;
+ }
+ case InstIcmp::Sgt: {
+ _slt(DestT, Src1R, Src0R);
+ _br(TargetTrue, TargetFalse, DestT, NULL, CondMIPS32::Cond::EQZ);
+ break;
+ }
+ case InstIcmp::Sge: {
+ _slt(DestT, Src0R, Src1R);
+ _br(TargetTrue, TargetFalse, DestT, NULL, CondMIPS32::Cond::NEZ);
+ break;
+ }
+ case InstIcmp::Slt: {
+ _slt(DestT, Src0R, Src1R);
+ _br(TargetTrue, TargetFalse, DestT, NULL, CondMIPS32::Cond::EQZ);
+ break;
+ }
+ case InstIcmp::Sle: {
+ _slt(DestT, Src1R, Src0R);
+ _br(TargetTrue, TargetFalse, DestT, NULL, CondMIPS32::Cond::NEZ);
+ break;
+ }
+ }
+ }
+ return;
John 2016/05/19 14:59:59 no need to "return" here.
sagar.thakur 2016/05/23 18:30:26 Done.
}
void TargetMIPS32::lowerCall(const InstCall *Instr) {
@@ -1410,6 +1482,71 @@ Operand *TargetMIPS32::legalize(Operand *From, LegalMask Allowed,
return From;
}
+namespace BoolFolding {
+// TODO(sagar.thakur): Add remaining instruction kinds to shouldTrackProducer()
+// and isValidConsumer()
+bool shouldTrackProducer(const Inst &Instr) {
+ return Instr.getKind() == Inst::Icmp;
+}
+
+bool isValidConsumer(const Inst &Instr) { return Instr.getKind() == Inst::Br; }
+} // end of namespace BoolFolding
+
+void TargetMIPS32::ComputationTracker::recordProducers(CfgNode *Node) {
+ for (Inst &Instr : Node->getInsts()) {
+ // Check whether Instr is a valid producer.
+ Variable *Dest = Instr.getDest();
+ if (!Instr.isDeleted() // only consider non-deleted instructions; and
Jim Stichnoth 2016/05/19 15:03:41 The isDeleted() check should be stronger. The who
sagar.thakur 2016/05/23 18:30:26 Done.
+ && Dest // only instructions with an actual dest var; and
+ && Dest->getType() == IceType_i1 // only bool-type dest vars; and
+ && BoolFolding::shouldTrackProducer(Instr)) { // white-listed instr.
+ KnownComputations.emplace(Dest->getIndex(),
+ ComputationEntry(&Instr, IceType_i1));
+ }
+ // Check each src variable against the map.
+ FOREACH_VAR_IN_INST(Var, Instr) {
+ SizeT VarNum = Var->getIndex();
+ auto ComputationIter = KnownComputations.find(VarNum);
+ if (ComputationIter == KnownComputations.end()) {
+ continue;
+ }
+
+ ++ComputationIter->second.NumUses;
+ switch (ComputationIter->second.ComputationType) {
+ default:
+ KnownComputations.erase(VarNum);
+ continue;
+ case IceType_i1:
+ if (!BoolFolding::isValidConsumer(Instr)) {
+ KnownComputations.erase(VarNum);
+ continue;
+ }
+ break;
+ }
+
+ if (Instr.isLastUse(Var)) {
+ ComputationIter->second.IsLiveOut = false;
+ }
+ }
+ }
+
+ for (auto Iter = KnownComputations.begin(), End = KnownComputations.end();
+ Iter != End;) {
+ // Disable the folding if its dest may be live beyond this block.
+ if (Iter->second.IsLiveOut || Iter->second.NumUses > 1) {
+ Iter = KnownComputations.erase(Iter);
+ continue;
+ }
+
+ // Mark as "dead" rather than outright deleting. This is so that other
+ // peephole style optimizations during or before lowering have access to
+ // this instruction in undeleted form. See for example
+ // tryOptimizedCmpxchgCmpBr().
+ Iter->second.Instr->setDead();
+ ++Iter;
+ }
+}
+
TargetHeaderMIPS32::TargetHeaderMIPS32(GlobalContext *Ctx)
: TargetHeaderLowering(Ctx) {}

Powered by Google App Engine
This is Rietveld 408576698