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

Side by Side 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 unified diff | Download patch
OLDNEW
1 //===- subzero/src/IceTargetLoweringMIPS32.cpp - MIPS32 lowering ----------===// 1 //===- subzero/src/IceTargetLoweringMIPS32.cpp - MIPS32 lowering ----------===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 /// 9 ///
10 /// \file 10 /// \file
11 /// \brief Implements the TargetLoweringMIPS32 class, which consists almost 11 /// \brief Implements the TargetLoweringMIPS32 class, which consists almost
12 /// entirely of the lowering sequence for each high-level instruction. 12 /// entirely of the lowering sequence for each high-level instruction.
13 /// 13 ///
14 //===----------------------------------------------------------------------===// 14 //===----------------------------------------------------------------------===//
15 15
16 #include "IceTargetLoweringMIPS32.h" 16 #include "IceTargetLoweringMIPS32.h"
17 17
18 #include "IceCfg.h" 18 #include "IceCfg.h"
19 #include "IceCfgNode.h" 19 #include "IceCfgNode.h"
20 #include "IceClFlags.h" 20 #include "IceClFlags.h"
21 #include "IceDefs.h" 21 #include "IceDefs.h"
22 #include "IceELFObjectWriter.h" 22 #include "IceELFObjectWriter.h"
23 #include "IceGlobalInits.h" 23 #include "IceGlobalInits.h"
24 #include "IceInstMIPS32.h" 24 #include "IceInstMIPS32.h"
25 #include "IceInstVarIter.h"
25 #include "IceLiveness.h" 26 #include "IceLiveness.h"
26 #include "IceOperand.h" 27 #include "IceOperand.h"
27 #include "IcePhiLoweringImpl.h" 28 #include "IcePhiLoweringImpl.h"
28 #include "IceRegistersMIPS32.h" 29 #include "IceRegistersMIPS32.h"
29 #include "IceTargetLoweringMIPS32.def" 30 #include "IceTargetLoweringMIPS32.def"
30 #include "IceUtils.h" 31 #include "IceUtils.h"
31 #include "llvm/Support/MathExtras.h" 32 #include "llvm/Support/MathExtras.h"
32 33
33 namespace MIPS32 { 34 namespace MIPS32 {
34 std::unique_ptr<::Ice::TargetLowering> createTargetLowering(::Ice::Cfg *Func) { 35 std::unique_ptr<::Ice::TargetLowering> createTargetLowering(::Ice::Cfg *Func) {
(...skipping 771 matching lines...) Expand 10 before | Expand all | Expand 10 after
806 _mov(Dest, SrcR); 807 _mov(Dest, SrcR);
807 } 808 }
808 } 809 }
809 } 810 }
810 811
811 void TargetMIPS32::lowerBr(const InstBr *Instr) { 812 void TargetMIPS32::lowerBr(const InstBr *Instr) {
812 if (Instr->isUnconditional()) { 813 if (Instr->isUnconditional()) {
813 _br(Instr->getTargetUnconditional()); 814 _br(Instr->getTargetUnconditional());
814 return; 815 return;
815 } 816 }
816 UnimplementedLoweringError(this, Instr); 817 CfgNode *TargetTrue = Instr->getTargetTrue();
818 CfgNode *TargetFalse = Instr->getTargetFalse();
819 Operand *Boolean = Instr->getCondition();
820 const Inst *Producer = Computations.getProducerOf(Boolean);
821 assert(Producer != nullptr);
822 if (Producer->getKind() == Inst::Icmp) {
823 const InstIcmp *CompareInst = llvm::cast<InstIcmp>(Producer);
824 Operand *Src0 = CompareInst->getSrc(0);
825 Operand *Src1 = CompareInst->getSrc(1);
826 const Type Src0Ty = Src0->getType();
827 const Type Src1Ty = Src1->getType();
828 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.
829 UnimplementedLoweringError(this, Instr);
830 return;
831 }
832 auto *Src0R = legalizeToReg(Src0);
833 auto *Src1R = legalizeToReg(Src1);
834 auto *DestT = makeReg(Src0Ty);
835 switch (CompareInst->getCondition()) {
836 default:
837 break;
838 case InstIcmp::Eq: {
839 _br(TargetTrue, TargetFalse, Src0R, Src1R, CondMIPS32::Cond::NE);
840 break;
841 }
842 case InstIcmp::Ne: {
843 _br(TargetTrue, TargetFalse, Src0R, Src1R, CondMIPS32::Cond::EQ);
844 break;
845 }
846 case InstIcmp::Ugt: {
847 _sltu(DestT, Src1R, Src0R);
848 _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.
849 break;
850 }
851 case InstIcmp::Uge: {
852 _sltu(DestT, Src0R, Src1R);
853 _br(TargetTrue, TargetFalse, DestT, NULL, CondMIPS32::Cond::NEZ);
854 break;
855 }
856 case InstIcmp::Ult: {
857 _sltu(DestT, Src0R, Src1R);
858 _br(TargetTrue, TargetFalse, DestT, NULL, CondMIPS32::Cond::EQZ);
859 break;
860 }
861 case InstIcmp::Ule: {
862 _sltu(DestT, Src1R, Src0R);
863 _br(TargetTrue, TargetFalse, DestT, NULL, CondMIPS32::Cond::NEZ);
864 break;
865 }
866 case InstIcmp::Sgt: {
867 _slt(DestT, Src1R, Src0R);
868 _br(TargetTrue, TargetFalse, DestT, NULL, CondMIPS32::Cond::EQZ);
869 break;
870 }
871 case InstIcmp::Sge: {
872 _slt(DestT, Src0R, Src1R);
873 _br(TargetTrue, TargetFalse, DestT, NULL, CondMIPS32::Cond::NEZ);
874 break;
875 }
876 case InstIcmp::Slt: {
877 _slt(DestT, Src0R, Src1R);
878 _br(TargetTrue, TargetFalse, DestT, NULL, CondMIPS32::Cond::EQZ);
879 break;
880 }
881 case InstIcmp::Sle: {
882 _slt(DestT, Src1R, Src0R);
883 _br(TargetTrue, TargetFalse, DestT, NULL, CondMIPS32::Cond::NEZ);
884 break;
885 }
886 }
887 }
888 return;
John 2016/05/19 14:59:59 no need to "return" here.
sagar.thakur 2016/05/23 18:30:26 Done.
817 } 889 }
818 890
819 void TargetMIPS32::lowerCall(const InstCall *Instr) { 891 void TargetMIPS32::lowerCall(const InstCall *Instr) {
820 // TODO(rkotler): assign arguments to registers and stack. Also reserve stack. 892 // TODO(rkotler): assign arguments to registers and stack. Also reserve stack.
821 if (Instr->getNumArgs()) { 893 if (Instr->getNumArgs()) {
822 UnimplementedLoweringError(this, Instr); 894 UnimplementedLoweringError(this, Instr);
823 return; 895 return;
824 } 896 }
825 // Generate the call instruction. Assign its result to a temporary with high 897 // Generate the call instruction. Assign its result to a temporary with high
826 // register allocation weight. 898 // register allocation weight.
(...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after
1403 // RegNum is required and Var->getRegNum() doesn't match. 1475 // RegNum is required and Var->getRegNum() doesn't match.
1404 if ((!(Allowed & Legal_Mem) && !MustHaveRegister) || 1476 if ((!(Allowed & Legal_Mem) && !MustHaveRegister) ||
1405 (RegNum.hasValue() && RegNum != Var->getRegNum())) { 1477 (RegNum.hasValue() && RegNum != Var->getRegNum())) {
1406 From = copyToReg(From, RegNum); 1478 From = copyToReg(From, RegNum);
1407 } 1479 }
1408 return From; 1480 return From;
1409 } 1481 }
1410 return From; 1482 return From;
1411 } 1483 }
1412 1484
1485 namespace BoolFolding {
1486 // TODO(sagar.thakur): Add remaining instruction kinds to shouldTrackProducer()
1487 // and isValidConsumer()
1488 bool shouldTrackProducer(const Inst &Instr) {
1489 return Instr.getKind() == Inst::Icmp;
1490 }
1491
1492 bool isValidConsumer(const Inst &Instr) { return Instr.getKind() == Inst::Br; }
1493 } // end of namespace BoolFolding
1494
1495 void TargetMIPS32::ComputationTracker::recordProducers(CfgNode *Node) {
1496 for (Inst &Instr : Node->getInsts()) {
1497 // Check whether Instr is a valid producer.
1498 Variable *Dest = Instr.getDest();
1499 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.
1500 && Dest // only instructions with an actual dest var; and
1501 && Dest->getType() == IceType_i1 // only bool-type dest vars; and
1502 && BoolFolding::shouldTrackProducer(Instr)) { // white-listed instr.
1503 KnownComputations.emplace(Dest->getIndex(),
1504 ComputationEntry(&Instr, IceType_i1));
1505 }
1506 // Check each src variable against the map.
1507 FOREACH_VAR_IN_INST(Var, Instr) {
1508 SizeT VarNum = Var->getIndex();
1509 auto ComputationIter = KnownComputations.find(VarNum);
1510 if (ComputationIter == KnownComputations.end()) {
1511 continue;
1512 }
1513
1514 ++ComputationIter->second.NumUses;
1515 switch (ComputationIter->second.ComputationType) {
1516 default:
1517 KnownComputations.erase(VarNum);
1518 continue;
1519 case IceType_i1:
1520 if (!BoolFolding::isValidConsumer(Instr)) {
1521 KnownComputations.erase(VarNum);
1522 continue;
1523 }
1524 break;
1525 }
1526
1527 if (Instr.isLastUse(Var)) {
1528 ComputationIter->second.IsLiveOut = false;
1529 }
1530 }
1531 }
1532
1533 for (auto Iter = KnownComputations.begin(), End = KnownComputations.end();
1534 Iter != End;) {
1535 // Disable the folding if its dest may be live beyond this block.
1536 if (Iter->second.IsLiveOut || Iter->second.NumUses > 1) {
1537 Iter = KnownComputations.erase(Iter);
1538 continue;
1539 }
1540
1541 // Mark as "dead" rather than outright deleting. This is so that other
1542 // peephole style optimizations during or before lowering have access to
1543 // this instruction in undeleted form. See for example
1544 // tryOptimizedCmpxchgCmpBr().
1545 Iter->second.Instr->setDead();
1546 ++Iter;
1547 }
1548 }
1549
1413 TargetHeaderMIPS32::TargetHeaderMIPS32(GlobalContext *Ctx) 1550 TargetHeaderMIPS32::TargetHeaderMIPS32(GlobalContext *Ctx)
1414 : TargetHeaderLowering(Ctx) {} 1551 : TargetHeaderLowering(Ctx) {}
1415 1552
1416 void TargetHeaderMIPS32::lower() { 1553 void TargetHeaderMIPS32::lower() {
1417 OstreamLocker L(Ctx); 1554 OstreamLocker L(Ctx);
1418 Ostream &Str = Ctx->getStrEmit(); 1555 Ostream &Str = Ctx->getStrEmit();
1419 Str << "\t.set\t" 1556 Str << "\t.set\t"
1420 << "nomicromips\n"; 1557 << "nomicromips\n";
1421 Str << "\t.set\t" 1558 Str << "\t.set\t"
1422 << "nomips16\n"; 1559 << "nomips16\n";
1423 } 1560 }
1424 1561
1425 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; 1562 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM];
1426 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; 1563 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM];
1427 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; 1564 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM];
1428 1565
1429 } // end of namespace MIPS32 1566 } // end of namespace MIPS32
1430 } // end of namespace Ice 1567 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698