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

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: Initial Implementation 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
11 /// \brief Implements the Cfg class. 11 /// \brief Implements the Cfg class.
12 /// 12 ///
13 //===----------------------------------------------------------------------===// 13 //===----------------------------------------------------------------------===//
14 14
15 #include "IceCfg.h" 15 #include "IceCfg.h"
16 16
17 #include "IceAssembler.h" 17 #include "IceAssembler.h"
18 #include "IceBitVector.h" 18 #include "IceBitVector.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 "IceInst.h" 24 #include "IceInst.h"
25 #include "IceInstVarIter.h" 25 #include "IceInstVarIter.h"
26 #include "IceLiveness.h" 26 #include "IceLiveness.h"
27 #include "IceLoopAnalyzer.h" 27 #include "IceLoopAnalyzer.h"
28 #include "IceOperand.h" 28 #include "IceOperand.h"
29 #include "IceTargetLowering.h" 29 #include "IceTargetLowering.h"
30
Jim Stichnoth 2016/05/19 01:35:50 don't remove this separator blank line
manasijm 2016/05/19 17:50:16 Done.
31 #include <memory> 30 #include <memory>
32 #include <utility> 31 #include <utility>
33 32
34 namespace Ice { 33 namespace Ice {
35 34
36 Cfg::Cfg(GlobalContext *Ctx, uint32_t SequenceNumber) 35 Cfg::Cfg(GlobalContext *Ctx, uint32_t SequenceNumber)
37 : Ctx(Ctx), SequenceNumber(SequenceNumber), VMask(getFlags().getVerbose()), 36 : Ctx(Ctx), SequenceNumber(SequenceNumber), VMask(getFlags().getVerbose()),
38 FunctionName(), NextInstNumber(Inst::NumberInitial), Live(nullptr) { 37 FunctionName(), NextInstNumber(Inst::NumberInitial), Live(nullptr) {
39 Allocator.reset(new ArenaAllocator()); 38 Allocator.reset(new ArenaAllocator());
40 NodeStrings.reset(new StringPool); 39 NodeStrings.reset(new StringPool);
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 for (CfgNode *Node : reverse_range(ReversedReachable)) 499 for (CfgNode *Node : reverse_range(ReversedReachable))
501 Shuffled.push_back(Node); 500 Shuffled.push_back(Node);
502 for (CfgNode *Node : Unreachable) 501 for (CfgNode *Node : Unreachable)
503 Shuffled.push_back(Node); 502 Shuffled.push_back(Node);
504 assert(Nodes.size() == Shuffled.size()); 503 assert(Nodes.size() == Shuffled.size());
505 swapNodes(Shuffled); 504 swapNodes(Shuffled);
506 505
507 dump("After basic block shuffling"); 506 dump("After basic block shuffling");
508 } 507 }
509 508
509 void Cfg::localCSE() {
Jim Stichnoth 2016/05/19 01:35:49 (putting this comment here for lack of a better pl
manasijm 2016/05/19 02:01:52 I have not managed to isolate a small example yet
510 TimerMarker T(TimerStack::TT_localCse, this);
511 struct InstHash {
512 size_t operator()(const Inst *Instr) const {
513 auto Kind = Instr->getKind();
514 auto Result =
515 std::hash<typename std::underlying_type<Inst::InstKind>::type>()(
516 Kind);
517 for (unsigned int i = 0; i < Instr->getSrcSize(); ++i) {
Jim Stichnoth 2016/05/19 01:35:50 SizeT instead of unsigned int
518 Operand *Opr = Instr->getSrc(i);
Jim Stichnoth 2016/05/19 01:35:49 I would name it not "Opr", but "Op" or "Opnd" to f
519 if (Variable *Var = llvm::dyn_cast<Variable>(Opr)) {
Jim Stichnoth 2016/05/19 01:35:49 auto *Var because the type is already clear from t
manasijm 2016/05/19 17:50:16 Done.
520 Result ^= std::hash<uint32_t>()(Var->getIndex());
Jim Stichnoth 2016/05/19 01:35:49 Can you use SizeT instead of uint32_t, to match th
manasijm 2016/05/19 17:50:16 Done.
521 } else if (Constant *Cst = llvm::dyn_cast<Constant>(Opr)) {
Jim Stichnoth 2016/05/19 01:35:49 Name it "Const" instead of "Cst" for consistency.
manasijm 2016/05/19 02:01:53 Ok, didn't do that in the first place because cons
522 Result ^= std::hash<Constant *>()(
523 Cst); // TODO : get Value ConstantPrimitive
Jim Stichnoth 2016/05/19 01:35:49 TODO(manasijm): get ... Also, probably put the TO
524 } else
525 Result ^= std::hash<Operand *>()(Opr);
526 }
527 return Result;
Jim Stichnoth 2016/05/19 01:35:49 Use early returns more aggressively, per http://ll
manasijm 2016/05/19 17:50:16 Not applicable here, all the sources has to be inc
528 }
529 };
530 struct InstEq {
531 bool operator()(Inst *const InstrA, Inst *const InstrB) const {
Jim Stichnoth 2016/05/19 01:35:48 Shouldn't this be "const Inst *InstrA"? Those are
manasijm 2016/05/19 02:01:53 I had some const correctness trouble with that. Wi
manasijm 2016/05/19 17:50:16 Done.
532 bool Result = (InstrA->getKind() == InstrB->getKind()) &&
533 (InstrA->getSrcSize() == InstrB->getSrcSize());
Jim Stichnoth 2016/05/19 01:35:48 I think this can be made clearer and more efficien
534
535 if (llvm::isa<InstArithmetic>(InstrA)) {
Jim Stichnoth 2016/05/19 01:35:49 if (auto *A = llvm::dyn_cast<InstArithmetic>(Instr
536 auto A = llvm::dyn_cast<InstArithmetic>(InstrA);
Jim Stichnoth 2016/05/19 01:35:49 auto *A auto *B
537 auto B = llvm::dyn_cast<InstArithmetic>(InstrB);
Jim Stichnoth 2016/05/19 01:35:50 use llvm::cast<> instead of llvm::dyn_cast<> here.
538 Result = Result && (A->getOp() == B->getOp());
539 }
540 // Does not enter loop if different kind or number of operands
541 for (unsigned int i = 0; i < InstrA->getSrcSize() && Result; ++i) {
Jim Stichnoth 2016/05/19 01:35:49 SizeT i
542 Result = Result && (InstrA->getSrc(i) == InstrB->getSrc(i));
Jim Stichnoth 2016/05/19 01:35:48 Be aware that Operand* pointer equality is fine wi
manasijm 2016/05/19 02:01:52 Or just returning false if they are not Constant*
543 }
544 return Result;
545 }
546 };
547 struct VariableHash {
548 size_t operator()(Variable *Var) const {
Jim Stichnoth 2016/05/19 01:35:49 const Variable * ?
549 return std::hash<uint32_t>()(Var->getIndex());
Jim Stichnoth 2016/05/19 01:35:49 Can this be SizeT instead of uint32_t?
550 }
551 };
552 for (CfgNode *Node : getNodes()) {
553 std::unordered_map<Inst *, Variable *, InstHash, InstEq,
Jim Stichnoth 2016/05/19 01:35:49 You should be able to do: CfgUnorderedMap<Inst *,
554 CfgLocalAllocator<std::pair<Inst *const, Variable *>>>
555 Seen;
556 // This could be converted to an unordered_set without much effort.
Jim Stichnoth 2016/05/19 01:35:48 If that's true, and reasonable, then just do it? Y
557 std::unordered_map<
558 Variable *, Variable *, VariableHash, std::equal_to<Variable *>,
559 CfgLocalAllocator<std::pair<Variable *const, Variable *>>> Replacements;
560 // Combining the above two into a single data structure
Jim Stichnoth 2016/05/19 01:35:50 Reflow comment to 80-col
561 // might consume less memory but will be slower
562 // i.e map of Instruction -> Vector/Set of Variables
563 std::unordered_map<
564 Variable *, std::vector<Inst *>, VariableHash,
565 std::equal_to<Variable *>,
566 CfgLocalAllocator<std::pair<Variable *const, std::vector<Inst *>>>>
567 Dependency;
568 // Not necessary for SSA, still keeping it in case this pass is
Jim Stichnoth 2016/05/19 01:35:50 reflow comment
569 // not run at the beginning. Remove to improve performace.
570
571 for (Inst &Instr : Node->getInsts()) {
572 if (Instr.isDeleted() || !llvm::isa<InstArithmetic>(&Instr))
573 continue;
574
575 auto Iter = Replacements.find(Instr.getDest());
576 if (Iter != Replacements.end()) {
577 Replacements.erase(Iter);
578 }
579
580 auto DIter = Dependency.find(Instr.getDest());
581 if (DIter != Dependency.end()) {
582 for (auto Dep : DIter->second) {
583 Seen.erase(Dep);
584 }
585 }
586
587 // replace - doing this before checking for repitions
Jim Stichnoth 2016/05/19 01:35:49 repetitions and reflow to 80-col
588 // might enable more optimizations
589 for (unsigned int i = 0; i < Instr.getSrcSize(); ++i) {
Jim Stichnoth 2016/05/19 01:35:48 SizeT
590 Operand *Opr = Instr.getSrc(i);
591 if (Variable *const Var = llvm::dyn_cast<Variable>(Opr)) {
Jim Stichnoth 2016/05/19 01:35:48 auto *
592 if (Replacements.find(Var) != Replacements.end()) {
593 Instr.replaceSource(i, Replacements[Var]);
594 }
595 }
596 }
597
598 // check for repititions
Jim Stichnoth 2016/05/19 01:35:48 repetitions
manasijm 2016/05/19 02:01:53 typo, will update on next patchset.
manasijm 2016/05/19 17:50:16 Done.
599
600 if (Seen.find(&Instr) != Seen.end()) { // seen before
601 Replacements[Instr.getDest()] = Seen[&Instr];
602 // Instr.setDeleted();
Jim Stichnoth 2016/05/19 01:35:49 remove commented-out line
manasijm 2016/05/19 17:50:16 Done.
603 } else { // new
604 Seen[&Instr] = Instr.getDest();
605
606 for (unsigned int i = 0; i < Instr.getSrcSize(); ++i) {
Jim Stichnoth 2016/05/19 01:35:49 SizeT
manasijm 2016/05/19 17:50:16 Done.
607 Operand *Opr = Instr.getSrc(i);
608 if (Variable *Var = llvm::dyn_cast<Variable>(Opr)) {
Jim Stichnoth 2016/05/19 01:35:49 auto *Var
manasijm 2016/05/19 17:50:16 Done.
609 Dependency[Var].push_back(&Instr);
610 }
611 }
612 }
613 }
614 }
615 }
616
510 void Cfg::doArgLowering() { 617 void Cfg::doArgLowering() {
511 TimerMarker T(TimerStack::TT_doArgLowering, this); 618 TimerMarker T(TimerStack::TT_doArgLowering, this);
512 getTarget()->lowerArguments(); 619 getTarget()->lowerArguments();
513 } 620 }
514 621
515 void Cfg::sortAndCombineAllocas(CfgVector<Inst *> &Allocas, 622 void Cfg::sortAndCombineAllocas(CfgVector<Inst *> &Allocas,
516 uint32_t CombinedAlignment, InstList &Insts, 623 uint32_t CombinedAlignment, InstList &Insts,
517 AllocaBaseVariableType BaseVariableType) { 624 AllocaBaseVariableType BaseVariableType) {
518 if (Allocas.empty()) 625 if (Allocas.empty())
519 return; 626 return;
(...skipping 958 matching lines...) Expand 10 before | Expand all | Expand 10 after
1478 } 1585 }
1479 } 1586 }
1480 // Print each basic block 1587 // Print each basic block
1481 for (CfgNode *Node : Nodes) 1588 for (CfgNode *Node : Nodes)
1482 Node->dump(this); 1589 Node->dump(this);
1483 if (isVerbose(IceV_Instructions)) 1590 if (isVerbose(IceV_Instructions))
1484 Str << "}\n"; 1591 Str << "}\n";
1485 } 1592 }
1486 1593
1487 } // end of namespace Ice 1594 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceCfg.h ('k') | src/IceClFlags.def » ('j') | src/IceClFlags.def » ('J')

Powered by Google App Engine
This is Rietveld 408576698