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

Unified Diff: src/IceInst.cpp

Issue 1234803007: Introduction of improved switch lowering. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Created 5 years, 5 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/IceInst.cpp
diff --git a/src/IceInst.cpp b/src/IceInst.cpp
index ecfb1b660f4e5327088373336e9a1582459fa208..eccfb45cad22a1a65d6929e8a4eb34ddd029fca9 100644
--- a/src/IceInst.cpp
+++ b/src/IceInst.cpp
@@ -19,6 +19,7 @@
#include "IceCfgNode.h"
#include "IceLiveness.h"
#include "IceOperand.h"
+#include "IceTargetLowering.h"
namespace Ice {
@@ -295,15 +296,17 @@ NodeList InstBr::getTerminatorEdges() const {
return OutEdges;
}
-bool InstBr::repointEdge(CfgNode *OldNode, CfgNode *NewNode) {
+bool InstBr::repointEdges(CfgNode *OldNode, CfgNode *NewNode) {
+ bool Found = false;
if (TargetFalse == OldNode) {
TargetFalse = NewNode;
- return true;
- } else if (TargetTrue == OldNode) {
+ Found = true;
+ }
+ if (TargetTrue == OldNode) {
TargetTrue = NewNode;
- return true;
+ Found = true;
}
- return false;
+ return Found;
}
InstCast::InstCast(Cfg *Func, OpKind CastKind, Variable *Dest, Operand *Source)
@@ -461,21 +464,25 @@ NodeList InstSwitch::getTerminatorEdges() const {
for (SizeT I = 0; I < NumCases; ++I) {
OutEdges.push_back(Labels[I]);
}
+ std::sort(OutEdges.begin(), OutEdges.end());
Jim Stichnoth 2015/07/15 19:17:42 What is the comparison function here? It needs to
ascull 2015/07/16 19:38:45 Done.
+ auto last = std::unique(OutEdges.begin(), OutEdges.end());
Jim Stichnoth 2015/07/15 19:17:42 capitalize Last per LLVM convention
ascull 2015/07/16 19:38:45 Done.
+ OutEdges.erase(last, OutEdges.end());
return OutEdges;
}
-bool InstSwitch::repointEdge(CfgNode *OldNode, CfgNode *NewNode) {
+bool InstSwitch::repointEdges(CfgNode *OldNode, CfgNode *NewNode) {
+ bool Found = false;
if (LabelDefault == OldNode) {
LabelDefault = NewNode;
- return true;
+ Found = true;
}
for (SizeT I = 0; I < NumCases; ++I) {
if (Labels[I] == OldNode) {
Labels[I] = NewNode;
- return true;
+ Found = true;
}
}
- return false;
+ return Found;
}
InstUnreachable::InstUnreachable(Cfg *Func)
@@ -504,6 +511,30 @@ InstFakeUse::InstFakeUse(Cfg *Func, Variable *Src)
InstFakeKill::InstFakeKill(Cfg *Func, const Inst *Linked)
: InstHighLevel(Func, Inst::FakeKill, 0, nullptr), Linked(Linked) {}
+InstJumpTable::InstJumpTable(Cfg *Func, SizeT NumTargets, CfgNode *Default)
+ : InstHighLevel(Func, Inst::JumpTable, 1, nullptr),
+ Number(Func->getTarget()->makeNextLabelNumber()), NumTargets(NumTargets) {
+ Targets = Func->allocateArrayOf<CfgNode *>(NumTargets);
+ for (SizeT I = 0; I < NumTargets; ++I)
+ Targets[I] = Default;
Jim Stichnoth 2015/07/15 19:17:42 For safety, maybe all of these could be initialize
ascull 2015/07/16 19:38:45 Every element of the jump table can be jumped to s
+}
+
+bool InstJumpTable::repointEdges(CfgNode *OldNode, CfgNode *NewNode) {
+ bool Found = false;
+ for (SizeT I = 0; I < NumTargets; ++I) {
+ if (Targets[I] == OldNode) {
+ Targets[I] = NewNode;
+ Found = true;
+ }
+ }
+ return Found;
+}
+
+IceString InstJumpTable::getName(const Cfg *Func) const {
+ return ".L" + Func->getFunctionName()
+ + "$jumptable$__" + std::to_string(Number);
+}
+
Type InstCall::getReturnType() const {
if (Dest == nullptr)
return IceType_void;
@@ -917,6 +948,39 @@ void InstFakeKill::dump(const Cfg *Func) const {
Str << "kill.pseudo scratch_regs";
}
+void InstJumpTable::emit(const Cfg *Func) const {
Jim Stichnoth 2015/07/15 19:17:42 This should be tied in to the target data lowering
ascull 2015/07/16 19:38:45 I'm going to be doing this for emitIAS which is st
Jim Stichnoth 2015/07/17 15:33:47 TODO is fine for now, thanks.
+ // TODO(ascull): should this be a target specific lowering (with access built
+ // in?) and just have InstJumpTable as a high level, similar to br? or should
+ // this follow the same path as emitIAS i.e. put it in global context and
+ // produce this code later?
+ if (!BuildDefs::dump())
+ return;
+ Ostream &Str = Func->getContext()->getStrEmit();
+ // TODO(ascull): softcode pointer size of 4
+ // TODO(ascull): is .long portable?
+ Str << "\n\t.section\t.rodata."
+ << Func->getFunctionName() << "$jumptable,\"a\",@progbits\n"
+ << "\t.align 4\n"
+ << getName(Func) << ":";
+ for (SizeT I = 0; I < NumTargets; ++I)
+ Str << "\n\t.long\t" << Targets[I]->getAsmName();
+ Str << "\n\n\t.text";
+}
+void InstJumpTable::emitIAS(const Cfg *Func) const {
jvoung (off chromium) 2015/07/15 18:32:01 add a newline between functions
ascull 2015/07/16 19:38:45 Done.
+ // TODO(ascull): put jump table in the global context for emision later
jvoung (off chromium) 2015/07/15 18:32:01 emision -> emission
ascull 2015/07/16 19:38:45 Done.
+ (void)Func;
+}
+
+void InstJumpTable::dump(const Cfg *Func) const {
+ if (!BuildDefs::dump())
+ return;
+ Ostream &Str = Func->getContext()->getStrDump();
+ Str << "jump table [";
+ for (SizeT I = 0; I < NumTargets; ++I)
+ Str << "\n " << Targets[I]->getName();
+ Str << "\n ]";
+}
+
void InstTarget::dump(const Cfg *Func) const {
if (!BuildDefs::dump())
return;

Powered by Google App Engine
This is Rietveld 408576698