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

Unified Diff: src/IceInst.cpp

Issue 205613002: Initial skeleton of Subzero. (Closed) Base URL: https://gerrit.chromium.org/gerrit/p/native_client/pnacl-subzero.git@master
Patch Set: Fix omissions from previous patchset. Created 6 years, 8 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
new file mode 100644
index 0000000000000000000000000000000000000000..e90e0d2056fb159b6d784ee1f031a31f172de304
--- /dev/null
+++ b/src/IceInst.cpp
@@ -0,0 +1,469 @@
+//===- subzero/src/IceInst.cpp - High-level instruction implementation ----===//
+//
+// The Subzero Code Generator
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Inst class, primarily the various
+// subclass constructors and dump routines.
+//
+//===----------------------------------------------------------------------===//
+
+#include "IceCfg.h"
+#include "IceCfgNode.h"
+#include "IceInst.h"
+#include "IceOperand.h"
+
+namespace Ice {
+
+Inst::Inst(IceCfg *Cfg, InstKind Kind, IceSize_t MaxSrcs, Variable *Dest)
+ : Kind(Kind), Number(Cfg->newInstNumber()), Deleted(false),
+ HasSideEffects(false), Dest(Dest), MaxSrcs(MaxSrcs), NumSrcs(0),
+ Srcs(Cfg->allocateArrayOf<Operand *>(MaxSrcs)) {}
+
+Inst::~Inst() {
+#ifdef ICE_NO_ARENAS
+ for (IceSize_t i = 0; i < getSrcSize(); ++i) {
+ Operand *Src = getSrc(i);
+ if (Src && !Src->isPooled()) {
+ delete Src;
+ }
+ }
+ delete[] Srcs;
+ if (getDest() && !getDest()->isPooled()) {
+ delete getDest();
+ }
JF 2014/04/23 03:51:28 Same thing on deletion, though it kind of seems li
Jim Stichnoth 2014/04/26 15:02:11 Done. And you're right, it was just wrong for the
+#endif // ICE_NO_ARENAS
+}
+
+void Inst::updateVars(CfgNode *Node) {
+ if (Dest)
+ Dest->setDefinition(this, Node);
+
+ IceSize_t VarIndex = 0;
+ for (IceSize_t I = 0; I < getSrcSize(); ++I) {
+ Operand *Src = getSrc(I);
+ IceSize_t NumVars = Src->getNumVars();
+ for (IceSize_t J = 0; J < NumVars; ++J, ++VarIndex) {
+ Variable *Var = Src->getVar(J);
+ Var->setUse(this, Node);
+ }
+ }
+}
+
+InstAlloca::InstAlloca(IceCfg *Cfg, Operand *ByteCount, uint32_t Align,
+ Variable *Dest)
+ : Inst(Cfg, Inst::Alloca, 1, Dest), Align(Align) {
+ addSource(ByteCount);
+}
+
+InstArithmetic::InstArithmetic(IceCfg *Cfg, OpKind Op, Variable *Dest,
+ Operand *Source1, Operand *Source2)
+ : Inst(Cfg, Inst::Arithmetic, 2, Dest), Op(Op) {
+ addSource(Source1);
+ addSource(Source2);
+}
+
+bool InstArithmetic::isCommutative() const {
+#define X(tag, str, commutative) \
+ case tag: \
+ return commutative;
+
+ switch (getOp()) { ICEINSTARITHMETIC_TABLE }
JF 2014/04/23 03:51:28 Load from a static const bool table instead: show
Jim Stichnoth 2014/04/26 15:02:11 Done.
+#undef X
+
+ assert(0); // should be unreachable
JF 2014/04/23 03:51:28 llvm_unreachable
Jim Stichnoth 2014/04/26 15:02:11 Done.
+ return false;
+}
+
+InstAssign::InstAssign(IceCfg *Cfg, Variable *Dest, Operand *Source)
+ : Inst(Cfg, Inst::Assign, 1, Dest) {
+ addSource(Source);
+}
+
+// If TargetTrue==TargetFalse, we turn it into an unconditional
+// branch. This ensures that, along with the 'switch' instruction
+// semantics, there is at most one edge from one node to another.
+InstBr::InstBr(IceCfg *Cfg, Operand *Source, CfgNode *TargetTrue,
+ CfgNode *TargetFalse)
+ : Inst(Cfg, Inst::Br, 1, NULL), TargetFalse(TargetFalse),
+ TargetTrue(TargetTrue) {
+ if (TargetTrue == TargetFalse) {
+ TargetTrue = NULL; // turn into unconditional version
+ } else {
+ addSource(Source);
+ }
+}
+
+InstBr::InstBr(IceCfg *Cfg, CfgNode *Target)
+ : Inst(Cfg, Inst::Br, 0, NULL), TargetFalse(Target), TargetTrue(NULL) {}
+
+NodeList InstBr::getTerminatorEdges() const {
+ NodeList OutEdges;
+ OutEdges.push_back(TargetFalse);
+ if (TargetTrue)
+ OutEdges.push_back(TargetTrue);
+ return OutEdges;
+}
+
+InstCast::InstCast(IceCfg *Cfg, OpKind CastKind, Variable *Dest,
+ Operand *Source)
+ : Inst(Cfg, Inst::Cast, 1, Dest), CastKind(CastKind) {
+ addSource(Source);
+}
+
+InstFcmp::InstFcmp(IceCfg *Cfg, FCond Condition, Variable *Dest,
+ Operand *Source1, Operand *Source2)
+ : Inst(Cfg, Inst::Fcmp, 2, Dest), Condition(Condition) {
+ addSource(Source1);
+ addSource(Source2);
+}
+
+InstIcmp::InstIcmp(IceCfg *Cfg, ICond Condition, Variable *Dest,
+ Operand *Source1, Operand *Source2)
+ : Inst(Cfg, Inst::Icmp, 2, Dest), Condition(Condition) {
+ addSource(Source1);
+ addSource(Source2);
+}
+
+InstLoad::InstLoad(IceCfg *Cfg, Variable *Dest, Operand *SourceAddr)
+ : Inst(Cfg, Inst::Load, 1, Dest) {
+ addSource(SourceAddr);
+}
+
+InstPhi::InstPhi(IceCfg *Cfg, IceSize_t MaxSrcs, Variable *Dest)
+ : Inst(Cfg, Phi, MaxSrcs, Dest) {
+ Labels = Cfg->allocateArrayOf<CfgNode *>(MaxSrcs);
+}
+
+// TODO: A Switch instruction (and maybe others) can add duplicate
+// edges. We may want to de-dup Phis and validate consistency (i.e.,
+// the source operands are the same for duplicate edges), though it
+// seems the current lowering code is OK with this situation.
+void InstPhi::addArgument(Operand *Source, CfgNode *Label) {
+ Labels[getSrcSize()] = Label;
+ addSource(Source);
+}
+
+InstRet::InstRet(IceCfg *Cfg, Operand *RetValue)
+ : Inst(Cfg, Ret, RetValue ? 1 : 0, NULL) {
+ if (RetValue)
+ addSource(RetValue);
+}
+
+InstSelect::InstSelect(IceCfg *Cfg, Variable *Dest, Operand *Condition,
+ Operand *SourceTrue, Operand *SourceFalse)
+ : Inst(Cfg, Inst::Select, 3, Dest) {
+ assert(Condition->getType() == IceType_i1);
+ addSource(Condition);
+ addSource(SourceTrue);
+ addSource(SourceFalse);
+}
+
+InstStore::InstStore(IceCfg *Cfg, Operand *Data, Operand *Addr)
+ : Inst(Cfg, Inst::Store, 2, NULL) {
+ addSource(Data);
+ addSource(Addr);
+}
+
+InstSwitch::InstSwitch(IceCfg *Cfg, IceSize_t NumCases, Operand *Source,
+ CfgNode *LabelDefault)
+ : Inst(Cfg, Inst::Switch, 1, NULL), LabelDefault(LabelDefault),
+ NumCases(NumCases) {
+ addSource(Source);
+ Values = Cfg->allocateArrayOf<uint64_t>(NumCases);
+ Labels = Cfg->allocateArrayOf<CfgNode *>(NumCases);
+ // Initialize in case buggy code doesn't set all entries
+ for (IceSize_t I = 0; I < NumCases; ++I) {
+ Values[I] = 0;
+ Labels[I] = NULL;
+ }
+}
+
+void InstSwitch::addBranch(IceSize_t CaseIndex, uint64_t Value,
+ CfgNode *Label) {
+ assert(CaseIndex < NumCases);
+ Values[CaseIndex] = Value;
+ Labels[CaseIndex] = Label;
+}
+
+NodeList InstSwitch::getTerminatorEdges() const {
+ NodeList OutEdges;
+ OutEdges.push_back(LabelDefault);
+ for (IceSize_t I = 0; I < NumCases; ++I) {
+ OutEdges.push_back(Labels[I]);
+ }
+ return OutEdges;
+}
+
+InstUnreachable::InstUnreachable(IceCfg *Cfg)
+ : Inst(Cfg, Inst::Unreachable, 0, NULL) {}
+
+// ======================== Dump routines ======================== //
+
+void Inst::dumpDecorated(const IceCfg *Cfg) const {
+ IceOstream &Str = Cfg->getContext()->getStrDump();
+ if (!Cfg->getContext()->isVerbose(IceV_Deleted) && isDeleted())
+ return;
+ if (Cfg->getContext()->isVerbose(IceV_InstNumbers)) {
+ const static size_t BufLen = 30;
+ char buf[BufLen];
+ int32_t Number = getNumber();
+ if (Number < 0)
+ snprintf(buf, BufLen, "[XXX]");
+ else
+ snprintf(buf, BufLen, "[%3d]", Number);
+ Str << buf;
+ }
+ Str << " ";
+ if (isDeleted())
+ Str << " //";
+ dump(Cfg);
+ Str << "\n";
+}
+
+void Inst::dump(const IceCfg *Cfg) const {
+ IceOstream &Str = Cfg->getContext()->getStrDump();
+ dumpDest(Cfg);
+ Str << " =~ ";
+ dumpSources(Cfg);
+}
+
+void Inst::dumpSources(const IceCfg *Cfg) const {
+ IceOstream &Str = Cfg->getContext()->getStrDump();
+ for (IceSize_t I = 0; I < getSrcSize(); ++I) {
+ if (I > 0)
+ Str << ", ";
+ getSrc(I)->dump(Cfg);
+ }
+}
+
+void Inst::dumpDest(const IceCfg *Cfg) const {
+ if (getDest())
+ getDest()->dump(Cfg);
+}
+
+void InstAlloca::dump(const IceCfg *Cfg) const {
+ IceOstream &Str = Cfg->getContext()->getStrDump();
+ dumpDest(Cfg);
+ Str << " = alloca i8, i32 ";
+ getSizeInBytes()->dump(Cfg);
+ Str << ", align " << Align;
+}
+
+void InstArithmetic::dump(const IceCfg *Cfg) const {
+ IceOstream &Str = Cfg->getContext()->getStrDump();
+ dumpDest(Cfg);
+ Str << " = ";
+
+#define X(tag, str, commutative) \
+ case tag: \
+ Str << str; \
+ break;
+
+ switch (getOp()) { ICEINSTARITHMETIC_TABLE }
JF 2014/04/23 03:51:28 Same thing on table lookup from static const char
Jim Stichnoth 2014/04/26 15:02:11 Done.
+#undef X
+
+ Str << " " << getDest()->getType() << " ";
+ dumpSources(Cfg);
+}
+
+void InstAssign::dump(const IceCfg *Cfg) const {
+ IceOstream &Str = Cfg->getContext()->getStrDump();
+ dumpDest(Cfg);
+ Str << " = " << getDest()->getType() << " ";
+ dumpSources(Cfg);
+}
+
+void InstBr::dump(const IceCfg *Cfg) const {
+ IceOstream &Str = Cfg->getContext()->getStrDump();
+ dumpDest(Cfg);
+ Str << "br ";
+ if (!isUnconditional()) {
+ Str << "i1 ";
+ getCondition()->dump(Cfg);
+ Str << ", label %" << getTargetTrue()->getName() << ", ";
+ }
+ Str << "label %" << getTargetFalse()->getName();
+}
+
+void InstCall::dump(const IceCfg *Cfg) const {
+ IceOstream &Str = Cfg->getContext()->getStrDump();
+ if (getDest()) {
+ dumpDest(Cfg);
+ Str << " = ";
+ }
+ if (Tail)
+ Str << "tail ";
+ Str << "call ";
+ if (getDest())
+ Str << getDest()->getType();
+ else
+ Str << "void";
+ Str << " ";
+ getCallTarget()->dump(Cfg);
+ Str << "(";
+ for (IceSize_t I = 0; I < getNumArgs(); ++I) {
+ if (I > 0)
+ Str << ", ";
+ Str << getArg(I)->getType() << " ";
+ getArg(I)->dump(Cfg);
+ }
+ Str << ")";
+}
+
+void InstCast::dump(const IceCfg *Cfg) const {
+ IceOstream &Str = Cfg->getContext()->getStrDump();
+ dumpDest(Cfg);
+ Str << " = ";
+
+#define X(tag, str) \
+ case tag: \
+ Str << str; \
+ break;
+
+ switch (getCastKind()) {
+ ICEINSTCAST_TABLE
JF 2014/04/23 03:51:28 Same.
Jim Stichnoth 2014/04/26 15:02:11 Done.
+ default:
+ Str << "UNKNOWN";
+ assert(0);
+ break;
+ }
+#undef X
+
+ Str << " " << getSrc(0)->getType() << " ";
+ dumpSources(Cfg);
+ Str << " to " << getDest()->getType();
+}
+
+void InstIcmp::dump(const IceCfg *Cfg) const {
+ IceOstream &Str = Cfg->getContext()->getStrDump();
+ dumpDest(Cfg);
+ Str << " = icmp ";
+
+#define X(tag, str) \
+ case tag: \
+ Str << str; \
+ break;
+
+ switch (getCondition()) { ICEINSTICMP_TABLE }
JF 2014/04/23 03:51:28 Same.
Jim Stichnoth 2014/04/26 15:02:11 Done.
+#undef X
+ Str << " " << getSrc(0)->getType() << " ";
+ dumpSources(Cfg);
+}
+
+void InstFcmp::dump(const IceCfg *Cfg) const {
+ IceOstream &Str = Cfg->getContext()->getStrDump();
+ dumpDest(Cfg);
+ Str << " = fcmp ";
+
+#define X(tag, str) \
+ case tag: \
+ Str << str; \
+ break;
+
+ switch (getCondition()) { ICEINSTFCMP_TABLE }
JF 2014/04/23 03:51:28 Same.
Jim Stichnoth 2014/04/26 15:02:11 Done.
+#undef X
+ Str << " " << getSrc(0)->getType() << " ";
+ dumpSources(Cfg);
+}
+
+void InstLoad::dump(const IceCfg *Cfg) const {
+ IceOstream &Str = Cfg->getContext()->getStrDump();
+ dumpDest(Cfg);
+ IceType Type = getDest()->getType();
+ Str << " = load " << Type << "* ";
+ dumpSources(Cfg);
+ switch (Type) {
+ case IceType_f32:
+ Str << ", align 4";
+ break;
+ case IceType_f64:
+ Str << ", align 8";
+ break;
+ default:
+ Str << ", align 1";
+ break;
+ }
+}
+
+void InstStore::dump(const IceCfg *Cfg) const {
+ IceOstream &Str = Cfg->getContext()->getStrDump();
+ IceType Type = getData()->getType();
+ Str << "store " << Type << " ";
+ getData()->dump(Cfg);
+ Str << ", " << Type << "* ";
+ getAddr()->dump(Cfg);
+ Str << ", align ";
+ switch (Type) {
+ case IceType_f32:
+ Str << "4";
+ break;
+ case IceType_f64:
+ Str << "8";
+ break;
+ default:
+ Str << "1";
+ break;
+ }
+}
+
+void InstSwitch::dump(const IceCfg *Cfg) const {
+ IceOstream &Str = Cfg->getContext()->getStrDump();
+ IceType Type = getComparison()->getType();
+ Str << "switch " << Type << " ";
+ getSrc(0)->dump(Cfg);
+ Str << ", label %" << getLabelDefault()->getName() << " [\n";
+ for (IceSize_t I = 0; I < getNumCases(); ++I) {
+ Str << " " << Type << " " << getValue(I) << ", label %"
+ << getLabel(I)->getName() << "\n";
+ }
+ Str << " ]";
+}
+
+void InstPhi::dump(const IceCfg *Cfg) const {
+ IceOstream &Str = Cfg->getContext()->getStrDump();
+ dumpDest(Cfg);
+ Str << " = phi " << getDest()->getType() << " ";
+ for (IceSize_t I = 0; I < getSrcSize(); ++I) {
+ if (I > 0)
+ Str << ", ";
+ Str << "[ ";
+ getSrc(I)->dump(Cfg);
+ Str << ", %" << Labels[I]->getName() << " ]";
+ }
+}
+
+void InstRet::dump(const IceCfg *Cfg) const {
+ IceOstream &Str = Cfg->getContext()->getStrDump();
+ IceType Type = hasRetValue() ? getSrc(0)->getType() : IceType_void;
+ Str << "ret " << Type;
+ if (hasRetValue()) {
+ Str << " ";
+ dumpSources(Cfg);
+ }
+}
+
+void InstSelect::dump(const IceCfg *Cfg) const {
+ IceOstream &Str = Cfg->getContext()->getStrDump();
+ dumpDest(Cfg);
+ Operand *Condition = getCondition();
+ Operand *TrueOp = getTrueOperand();
+ Operand *FalseOp = getFalseOperand();
+ Str << " = select " << Condition->getType() << " ";
+ Condition->dump(Cfg);
+ Str << ", " << TrueOp->getType() << " ";
+ TrueOp->dump(Cfg);
+ Str << ", " << FalseOp->getType() << " ";
+ FalseOp->dump(Cfg);
+}
+
+void InstUnreachable::dump(const IceCfg *Cfg) const {
+ IceOstream &Str = Cfg->getContext()->getStrDump();
+ Str << "unreachable";
+}
+
+} // end of namespace Ice

Powered by Google App Engine
This is Rietveld 408576698