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

Side by Side Diff: src/IceCfg.cpp

Issue 1997443002: Subzero: Initial implementation of BB Local CSE (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Modify test for x8632 and 64 to check with and without local-cse 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/IceCfg.cpp - Control flow graph implementation ---------===// 1 //===- subzero/src/IceCfg.cpp - Control flow graph implementation ---------===//
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
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 for (CfgNode *Node : reverse_range(ReversedReachable)) 500 for (CfgNode *Node : reverse_range(ReversedReachable))
501 Shuffled.push_back(Node); 501 Shuffled.push_back(Node);
502 for (CfgNode *Node : Unreachable) 502 for (CfgNode *Node : Unreachable)
503 Shuffled.push_back(Node); 503 Shuffled.push_back(Node);
504 assert(Nodes.size() == Shuffled.size()); 504 assert(Nodes.size() == Shuffled.size());
505 swapNodes(Shuffled); 505 swapNodes(Shuffled);
506 506
507 dump("After basic block shuffling"); 507 dump("After basic block shuffling");
508 } 508 }
509 509
510 void Cfg::localCSE() {
Jim Stichnoth 2016/05/23 16:52:56 I'd like to have a comment here briefly describing
manasijm 2016/05/23 23:13:30 Done.
511 TimerMarker T(TimerStack::TT_localCse, this);
512 struct InstHash {
513 size_t operator()(const Inst *Instr) const {
514 auto Kind = Instr->getKind();
515 auto Result =
516 std::hash<typename std::underlying_type<Inst::InstKind>::type>()(
517 Kind);
518 for (SizeT i = 0; i < Instr->getSrcSize(); ++i) {
519 auto *Opnd = Instr->getSrc(i);
520 if (auto *Var = llvm::dyn_cast<Variable>(Opnd)) {
521 Result ^= std::hash<SizeT>()(Var->getIndex());
Jim Stichnoth 2016/05/23 16:52:57 This is a repetition of the VariableHash implement
manasijm 2016/05/23 23:13:30 Done.
522 } else if (Constant *Const = llvm::dyn_cast<Constant>(Opnd)) {
523 Result ^= std::hash<Constant *>()(Const);
524 // TODO : get Value of ConstantPrimitive
Jim Stichnoth 2016/05/23 16:52:57 If I understand this correctly, your hash function
manasijm 2016/05/23 23:13:30 Done.
525 } else
526 Result ^= std::hash<Operand *>()(Opnd);
527 }
528 return Result;
529 }
530 };
531 struct InstEq {
532 bool srcEq(const Operand *A, const Operand *B) const {
533 if (!(llvm::isa<Variable>(A) || (llvm::isa<Constant>(A))) ||
Jim Stichnoth 2016/05/23 16:52:56 This is really hard to read/understand. How about
manasijm 2016/05/23 23:13:30 Done.
534 !(llvm::isa<Variable>(B) || (llvm::isa<Constant>(B))))
535 return false;
536 // No reason this has to an error. Returning false just disables the cse
Jim Stichnoth 2016/05/23 16:52:57 "has to an error" ==> "has to be an error" ? And
537 // optimization for this particular case
538 return (A == B);
539 }
540 bool operator()(const Inst *InstrA, const Inst *InstrB) const {
541 if ((InstrA->getKind() != InstrB->getKind()) ||
542 (InstrA->getSrcSize() != InstrB->getSrcSize()))
543 return false;
544
545 if (auto *A = llvm::dyn_cast<InstArithmetic>(InstrA)) {
546 auto B = llvm::cast<InstArithmetic>(InstrB);
Jim Stichnoth 2016/05/23 16:52:56 auto *
manasijm 2016/05/23 23:13:30 Done.
547 // A, B are guranteed to be of the same 'kind' at this point
Jim Stichnoth 2016/05/23 16:52:57 guaranteed
manasijm 2016/05/23 23:13:30 Done.
548 // So, dyn_Cast is not needed
Jim Stichnoth 2016/05/23 16:52:57 dyn_cast
manasijm 2016/05/23 23:13:30 Done.
549 if (A->getOp() != B->getOp())
550 return false;
551 }
552 // Does not enter loop if different kind or number of operands
553 for (SizeT i = 0; i < InstrA->getSrcSize(); ++i) {
554 if (!srcEq(InstrA->getSrc(i), InstrB->getSrc(i)))
555 return false;
556 }
557 return true;
558 }
559 };
560 struct VariableHash {
561 size_t operator()(const Variable *Var) const {
562 return std::hash<SizeT>()(Var->getIndex());
563 }
564 };
565 for (CfgNode *Node : getNodes()) {
566 CfgUnorderedSet<Inst *, InstHash, InstEq> Seen;
567
568 CfgUnorderedMap<Variable *, Variable *, VariableHash> Replacements;
569 // Combining the above two into a single data structure might consume less
570 // memory but will be slower i.e map of Instruction -> Set of Variables
571
572 CfgUnorderedMap<Variable *, std::vector<Inst *>, VariableHash> Dependency;
573 // Not necessary for SSA, still keeping it in case this pass is not run at
574 // the beginning. Remove to improve performace.
575
576 for (Inst &Instr : Node->getInsts()) {
577 if (Instr.isDeleted() || !llvm::isa<InstArithmetic>(&Instr))
578 continue;
579
580 // Invalidate replacements
581 auto Iter = Replacements.find(Instr.getDest());
582 if (Iter != Replacements.end()) {
583 Replacements.erase(Iter);
584 }
585
586 // Invalidate 'seen' instructions whose operands were just updated.
587 auto DepIter = Dependency.find(Instr.getDest());
588 if (DepIter != Dependency.end()) {
589 for (auto Dep : DepIter->second) {
Jim Stichnoth 2016/05/23 16:52:57 I think this use of "auto" is getting too deep for
manasijm 2016/05/23 23:13:30 Done.
590 Seen.erase(Dep);
591 }
592 }
593 // The above two can be removed if SSA is assumed.
594
595 // Replace - doing this before checking for repetitions might enable more
596 // optimizations
597 for (SizeT i = 0; i < Instr.getSrcSize(); ++i) {
598 auto *Opnd = Instr.getSrc(i);
599 if (Variable *const Var = llvm::dyn_cast<Variable>(Opnd)) {
Jim Stichnoth 2016/05/23 16:52:57 "Variable *const Var" just means that the value of
manasijm 2016/05/23 23:13:30 Artifact from first patch set.
600 if (Replacements.find(Var) != Replacements.end()) {
601 Instr.replaceSource(i, Replacements[Var]);
602 }
603 }
604 }
605
606 // Check for repetitions
607 auto SeenIter = Seen.find(&Instr);
608 if (SeenIter != Seen.end()) { // seen before
609 const Inst *Found = *SeenIter;
610 Replacements[Instr.getDest()] = Found->getDest();
611 } else { // new
612 Seen.insert(&Instr);
613
614 // Update dependencies
615 for (SizeT i = 0; i < Instr.getSrcSize(); ++i) {
616 auto *Opnd = Instr.getSrc(i);
617 if (auto *Var = llvm::dyn_cast<Variable>(Opnd)) {
618 Dependency[Var].push_back(&Instr);
619 }
620 }
621 }
622 }
623 }
624 }
625
510 void Cfg::doArgLowering() { 626 void Cfg::doArgLowering() {
511 TimerMarker T(TimerStack::TT_doArgLowering, this); 627 TimerMarker T(TimerStack::TT_doArgLowering, this);
512 getTarget()->lowerArguments(); 628 getTarget()->lowerArguments();
513 } 629 }
514 630
515 void Cfg::sortAndCombineAllocas(CfgVector<Inst *> &Allocas, 631 void Cfg::sortAndCombineAllocas(CfgVector<Inst *> &Allocas,
516 uint32_t CombinedAlignment, InstList &Insts, 632 uint32_t CombinedAlignment, InstList &Insts,
517 AllocaBaseVariableType BaseVariableType) { 633 AllocaBaseVariableType BaseVariableType) {
518 if (Allocas.empty()) 634 if (Allocas.empty())
519 return; 635 return;
(...skipping 958 matching lines...) Expand 10 before | Expand all | Expand 10 after
1478 } 1594 }
1479 } 1595 }
1480 // Print each basic block 1596 // Print each basic block
1481 for (CfgNode *Node : Nodes) 1597 for (CfgNode *Node : Nodes)
1482 Node->dump(this); 1598 Node->dump(this);
1483 if (isVerbose(IceV_Instructions)) 1599 if (isVerbose(IceV_Instructions))
1484 Str << "}\n"; 1600 Str << "}\n";
1485 } 1601 }
1486 1602
1487 } // end of namespace Ice 1603 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceCfg.h ('k') | src/IceClFlags.def » ('j') | tests_lit/llvm2ice_tests/local-cse.ll » ('J')

Powered by Google App Engine
This is Rietveld 408576698