Index: src/IceInst.h |
diff --git a/src/IceInst.h b/src/IceInst.h |
index 80b2bd2622978621b7857b7942f744b321ac7abb..a727683011523fe5956711160d962f4bc362658a 100644 |
--- a/src/IceInst.h |
+++ b/src/IceInst.h |
@@ -25,9 +25,9 @@ |
// TODO: The Cfg structure, and instructions in particular, need to be |
// validated for things like valid operand types, valid branch targets, proper |
-// ordering of Phi and non-Phi instructions, etc. Most of the validity |
-// checking will be done in the bitcode reader. We need a list of everything |
-// that should be validated, and tests for each. |
+// ordering of Phi and non-Phi instructions, etc. Most of the validity checking |
+// will be done in the bitcode reader. We need a list of everything that should |
+// be validated, and tests for each. |
namespace Ice { |
@@ -118,9 +118,9 @@ public: |
return NodeList(); |
} |
virtual bool isUnconditionalBranch() const { return false; } |
- /// If the instruction is a branch-type instruction with OldNode as a |
- /// target, repoint it to NewNode and return true, otherwise return |
- /// false. Repoint all instances of OldNode as a target. |
+ /// If the instruction is a branch-type instruction with OldNode as a target, |
+ /// repoint it to NewNode and return true, otherwise return false. Repoint all |
+ /// instances of OldNode as a target. |
virtual bool repointEdges(CfgNode *OldNode, CfgNode *NewNode) { |
(void)OldNode; |
(void)NewNode; |
@@ -130,11 +130,11 @@ public: |
virtual bool isSimpleAssign() const { return false; } |
void livenessLightweight(Cfg *Func, LivenessBV &Live); |
- // Calculates liveness for this instruction. Returns true if this |
- /// instruction is (tentatively) still live and should be retained, and false |
- /// if this instruction is (tentatively) dead and should be deleted. The |
- /// decision is tentative until the liveness dataflow algorithm has converged, |
- /// and then a separate pass permanently deletes dead instructions. |
+ /// Calculates liveness for this instruction. Returns true if this instruction |
+ /// is (tentatively) still live and should be retained, and false if this |
+ /// instruction is (tentatively) dead and should be deleted. The decision is |
+ /// tentative until the liveness dataflow algorithm has converged, and then a |
+ /// separate pass permanently deletes dead instructions. |
bool liveness(InstNumberT InstNumber, LivenessBV &Live, Liveness *Liveness, |
LiveBeginEndMap *LiveBegin, LiveBeginEndMap *LiveEnd); |
@@ -143,13 +143,12 @@ public: |
/// instructions, and a target-specific instruction results in a single native |
/// instruction. |
virtual uint32_t getEmitInstCount() const { return 0; } |
- // TODO(stichnot): Change Inst back to abstract once the g++ build |
- // issue is fixed. llvm::ilist<Ice::Inst> doesn't work under g++ |
- // because the resize(size_t, Ice::Inst) method is incorrectly |
- // declared and thus doesn't allow the abstract class Ice::Inst. |
- // The method should be declared resize(size_t, const Ice::Inst &). |
- // virtual void emit(const Cfg *Func) const = 0; |
- // virtual void emitIAS(const Cfg *Func) const = 0; |
+ // TODO(stichnot): Change Inst back to abstract once the g++ build issue is |
+ // fixed. llvm::ilist<Ice::Inst> doesn't work under g++ because the |
+ // resize(size_t, Ice::Inst) method is incorrectly declared and thus doesn't |
+ // allow the abstract class Ice::Inst. The method should be declared |
+ // resize(size_t, const Ice::Inst &). virtual void emit(const Cfg *Func) |
+ // const = 0; virtual void emitIAS(const Cfg *Func) const = 0; |
virtual void emit(const Cfg *) const { |
llvm_unreachable("emit on abstract class"); |
} |
@@ -179,8 +178,8 @@ protected: |
LiveRangesEnded |= (((LREndedBits)1u) << VarIndex); |
} |
void resetLastUses() { LiveRangesEnded = 0; } |
- /// The destroy() method lets the instruction cleanly release any |
- /// memory that was allocated via the Cfg's allocator. |
+ /// The destroy() method lets the instruction cleanly release any memory that |
+ /// was allocated via the Cfg's allocator. |
virtual void destroy(Cfg *Func) { Func->deallocateArrayOf<Operand *>(Srcs); } |
const InstKind Kind; |
@@ -188,17 +187,17 @@ protected: |
InstNumberT Number; |
/// Deleted means irrevocably deleted. |
bool Deleted = false; |
- /// Dead means one of two things depending on context: (1) pending |
- /// deletion after liveness analysis converges, or (2) marked for |
- /// deletion during lowering due to a folded bool operation. |
+ /// Dead means one of two things depending on context: (1) pending deletion |
+ /// after liveness analysis converges, or (2) marked for deletion during |
+ /// lowering due to a folded bool operation. |
bool Dead = false; |
- /// HasSideEffects means the instruction is something like a function |
- /// call or a volatile load that can't be removed even if its Dest |
- /// variable is not live. |
+ /// HasSideEffects means the instruction is something like a function call or |
+ /// a volatile load that can't be removed even if its Dest variable is not |
+ /// live. |
bool HasSideEffects = false; |
- /// IsDestNonKillable means that liveness analysis shouldn't consider |
- /// this instruction to kill the Dest variable. This is used when |
- /// lowering produces two assignments to the same variable. |
+ /// IsDestNonKillable means that liveness analysis shouldn't consider this |
+ /// instruction to kill the Dest variable. This is used when lowering produces |
+ /// two assignments to the same variable. |
bool IsDestNonKillable = false; |
Variable *Dest; |
@@ -207,13 +206,12 @@ protected: |
Operand **Srcs; |
/// LiveRangesEnded marks which Variables' live ranges end in this |
- /// instruction. An instruction can have an arbitrary number of |
- /// source operands (e.g. a call instruction), and each source |
- /// operand can contain 0 or 1 Variable (and target-specific operands |
- /// could contain more than 1 Variable). All the variables in an |
- /// instruction are conceptually flattened and each variable is |
- /// mapped to one bit position of the LiveRangesEnded bit vector. |
- /// Only the first CHAR_BIT * sizeof(LREndedBits) variables are |
+ /// instruction. An instruction can have an arbitrary number of source |
+ /// operands (e.g. a call instruction), and each source operand can contain 0 |
+ /// or 1 Variable (and target-specific operands could contain more than 1 |
+ /// Variable). All the variables in an instruction are conceptually flattened |
+ /// and each variable is mapped to one bit position of the LiveRangesEnded bit |
+ /// vector. Only the first CHAR_BIT * sizeof(LREndedBits) variables are |
/// tracked this way. |
using LREndedBits = uint32_t; // only first 32 src operands tracked, sorry |
LREndedBits LiveRangesEnded; |
@@ -235,9 +233,9 @@ protected: |
} |
}; |
-/// Alloca instruction. This captures the size in bytes as getSrc(0), |
-/// and the required alignment in bytes. The alignment must be either |
-/// 0 (no alignment required) or a power of 2. |
+/// Alloca instruction. This captures the size in bytes as getSrc(0), and the |
+/// required alignment in bytes. The alignment must be either 0 (no alignment |
+/// required) or a power of 2. |
class InstAlloca : public InstHighLevel { |
InstAlloca() = delete; |
InstAlloca(const InstAlloca &) = delete; |
@@ -261,8 +259,8 @@ private: |
const uint32_t AlignInBytes; |
}; |
-/// Binary arithmetic instruction. The source operands are captured in |
-/// getSrc(0) and getSrc(1). |
+/// Binary arithmetic instruction. The source operands are captured in getSrc(0) |
+/// and getSrc(1). |
class InstArithmetic : public InstHighLevel { |
InstArithmetic() = delete; |
InstArithmetic(const InstArithmetic &) = delete; |
@@ -296,12 +294,11 @@ private: |
const OpKind Op; |
}; |
-/// Assignment instruction. The source operand is captured in |
-/// getSrc(0). This is not part of the LLVM bitcode, but is a useful |
-/// abstraction for some of the lowering. E.g., if Phi instruction |
-/// lowering happens before target lowering, or for representing an |
-/// Inttoptr instruction, or as an intermediate step for lowering a |
-/// Load instruction. |
+/// Assignment instruction. The source operand is captured in getSrc(0). This is |
+/// not part of the LLVM bitcode, but is a useful abstraction for some of the |
+/// lowering. E.g., if Phi instruction lowering happens before target lowering, |
+/// or for representing an Inttoptr instruction, or as an intermediate step for |
+/// lowering a Load instruction. |
class InstAssign : public InstHighLevel { |
InstAssign() = delete; |
InstAssign(const InstAssign &) = delete; |
@@ -319,16 +316,16 @@ private: |
InstAssign(Cfg *Func, Variable *Dest, Operand *Source); |
}; |
-/// Branch instruction. This represents both conditional and |
-/// unconditional branches. |
+/// Branch instruction. This represents both conditional and unconditional |
+/// branches. |
class InstBr : public InstHighLevel { |
InstBr() = delete; |
InstBr(const InstBr &) = delete; |
InstBr &operator=(const InstBr &) = delete; |
public: |
- /// Create a conditional branch. If TargetTrue==TargetFalse, it is |
- /// optimized to an unconditional branch. |
+ /// Create a conditional branch. If TargetTrue==TargetFalse, it is optimized |
+ /// to an unconditional branch. |
static InstBr *create(Cfg *Func, Operand *Source, CfgNode *TargetTrue, |
CfgNode *TargetFalse) { |
return new (Func->allocate<InstBr>()) |
@@ -365,8 +362,8 @@ private: |
CfgNode *TargetTrue; /// nullptr if unconditional branch |
}; |
-/// Call instruction. The call target is captured as getSrc(0), and |
-/// arg I is captured as getSrc(I+1). |
+/// Call instruction. The call target is captured as getSrc(0), and arg I is |
+/// captured as getSrc(I+1). |
class InstCall : public InstHighLevel { |
InstCall() = delete; |
InstCall(const InstCall &) = delete; |
@@ -376,8 +373,8 @@ public: |
static InstCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest, |
Operand *CallTarget, bool HasTailCall) { |
/// Set HasSideEffects to true so that the call instruction can't be |
- /// dead-code eliminated. IntrinsicCalls can override this if the |
- /// particular intrinsic is deletable and has no side-effects. |
+ /// dead-code eliminated. IntrinsicCalls can override this if the particular |
+ /// intrinsic is deletable and has no side-effects. |
const bool HasSideEffects = true; |
const InstKind Kind = Inst::Call; |
return new (Func->allocate<InstCall>()) InstCall( |
@@ -458,8 +455,8 @@ private: |
Operand *Source2); |
}; |
-/// Floating-point comparison instruction. The source operands are |
-/// captured in getSrc(0) and getSrc(1). |
+/// Floating-point comparison instruction. The source operands are captured in |
+/// getSrc(0) and getSrc(1). |
class InstFcmp : public InstHighLevel { |
InstFcmp() = delete; |
InstFcmp(const InstFcmp &) = delete; |
@@ -489,8 +486,8 @@ private: |
const FCond Condition; |
}; |
-/// Integer comparison instruction. The source operands are captured |
-/// in getSrc(0) and getSrc(1). |
+/// Integer comparison instruction. The source operands are captured in |
+/// getSrc(0) and getSrc(1). |
class InstIcmp : public InstHighLevel { |
InstIcmp() = delete; |
InstIcmp(const InstIcmp &) = delete; |
@@ -543,8 +540,8 @@ private: |
Operand *Source2, Operand *Source3); |
}; |
-/// Call to an intrinsic function. The call target is captured as getSrc(0), |
-/// and arg I is captured as getSrc(I+1). |
+/// Call to an intrinsic function. The call target is captured as getSrc(0), and |
+/// arg I is captured as getSrc(I+1). |
class InstIntrinsicCall : public InstCall { |
InstIntrinsicCall() = delete; |
InstIntrinsicCall(const InstIntrinsicCall &) = delete; |
@@ -573,7 +570,7 @@ private: |
const Intrinsics::IntrinsicInfo Info; |
}; |
-/// Load instruction. The source address is captured in getSrc(0). |
+/// Load instruction. The source address is captured in getSrc(0). |
class InstLoad : public InstHighLevel { |
InstLoad() = delete; |
InstLoad(const InstLoad &) = delete; |
@@ -594,8 +591,8 @@ private: |
InstLoad(Cfg *Func, Variable *Dest, Operand *SourceAddr); |
}; |
-/// Phi instruction. For incoming edge I, the node is Labels[I] and |
-/// the Phi source operand is getSrc(I). |
+/// Phi instruction. For incoming edge I, the node is Labels[I] and the Phi |
+/// source operand is getSrc(I). |
class InstPhi : public InstHighLevel { |
InstPhi() = delete; |
InstPhi(const InstPhi &) = delete; |
@@ -621,15 +618,15 @@ private: |
Inst::destroy(Func); |
} |
- /// Labels[] duplicates the InEdges[] information in the enclosing |
- /// CfgNode, but the Phi instruction is created before InEdges[] |
- /// is available, so it's more complicated to share the list. |
+ /// Labels[] duplicates the InEdges[] information in the enclosing CfgNode, |
+ /// but the Phi instruction is created before InEdges[] is available, so it's |
+ /// more complicated to share the list. |
CfgNode **Labels; |
}; |
-/// Ret instruction. The return value is captured in getSrc(0), but if |
-/// there is no return value (void-type function), then |
-/// getSrcSize()==0 and hasRetValue()==false. |
+/// Ret instruction. The return value is captured in getSrc(0), but if there is |
+/// no return value (void-type function), then getSrcSize()==0 and |
+/// hasRetValue()==false. |
class InstRet : public InstHighLevel { |
InstRet() = delete; |
InstRet(const InstRet &) = delete; |
@@ -675,8 +672,8 @@ private: |
Operand *Source2); |
}; |
-/// Store instruction. The address operand is captured, along with the |
-/// data operand to be stored into the address. |
+/// Store instruction. The address operand is captured, along with the data |
+/// operand to be stored into the address. |
class InstStore : public InstHighLevel { |
InstStore() = delete; |
InstStore(const InstStore &) = delete; |
@@ -700,8 +697,7 @@ private: |
InstStore(Cfg *Func, Operand *Data, Operand *Addr); |
}; |
-/// Switch instruction. The single source operand is captured as |
-/// getSrc(0). |
+/// Switch instruction. The single source operand is captured as getSrc(0). |
class InstSwitch : public InstHighLevel { |
InstSwitch() = delete; |
InstSwitch(const InstSwitch &) = delete; |
@@ -744,8 +740,7 @@ private: |
CfgNode **Labels; /// size is NumCases |
}; |
-/// Unreachable instruction. This is a terminator instruction with no |
-/// operands. |
+/// Unreachable instruction. This is a terminator instruction with no operands. |
class InstUnreachable : public InstHighLevel { |
InstUnreachable() = delete; |
InstUnreachable(const InstUnreachable &) = delete; |
@@ -765,7 +760,7 @@ private: |
explicit InstUnreachable(Cfg *Func); |
}; |
-/// BundleLock instruction. There are no operands. Contains an option |
+/// BundleLock instruction. There are no operands. Contains an option |
/// indicating whether align_to_end is specified. |
class InstBundleLock : public InstHighLevel { |
InstBundleLock() = delete; |
@@ -791,7 +786,7 @@ private: |
InstBundleLock(Cfg *Func, Option BundleOption); |
}; |
-/// BundleUnlock instruction. There are no operands. |
+/// BundleUnlock instruction. There are no operands. |
class InstBundleUnlock : public InstHighLevel { |
InstBundleUnlock() = delete; |
InstBundleUnlock(const InstBundleUnlock &) = delete; |
@@ -812,18 +807,17 @@ private: |
explicit InstBundleUnlock(Cfg *Func); |
}; |
-/// FakeDef instruction. This creates a fake definition of a variable, |
-/// which is how we represent the case when an instruction produces |
-/// multiple results. This doesn't happen with high-level ICE |
-/// instructions, but might with lowered instructions. For example, |
-/// this would be a way to represent condition flags being modified by |
-/// an instruction. |
+/// FakeDef instruction. This creates a fake definition of a variable, which is |
+/// how we represent the case when an instruction produces multiple results. |
+/// This doesn't happen with high-level ICE instructions, but might with lowered |
+/// instructions. For example, this would be a way to represent condition flags |
+/// being modified by an instruction. |
/// |
-/// It's generally useful to set the optional source operand to be the |
-/// dest variable of the instruction that actually produces the FakeDef |
-/// dest. Otherwise, the original instruction could be dead-code |
-/// eliminated if its dest operand is unused, and therefore the FakeDef |
-/// dest wouldn't be properly initialized. |
+/// It's generally useful to set the optional source operand to be the dest |
+/// variable of the instruction that actually produces the FakeDef dest. |
+/// Otherwise, the original instruction could be dead-code eliminated if its |
+/// dest operand is unused, and therefore the FakeDef dest wouldn't be properly |
+/// initialized. |
class InstFakeDef : public InstHighLevel { |
InstFakeDef() = delete; |
InstFakeDef(const InstFakeDef &) = delete; |
@@ -843,11 +837,10 @@ private: |
InstFakeDef(Cfg *Func, Variable *Dest, Variable *Src); |
}; |
-/// FakeUse instruction. This creates a fake use of a variable, to |
-/// keep the instruction that produces that variable from being |
-/// dead-code eliminated. This is useful in a variety of lowering |
-/// situations. The FakeUse instruction has no dest, so it can itself |
-/// never be dead-code eliminated. |
+/// FakeUse instruction. This creates a fake use of a variable, to keep the |
+/// instruction that produces that variable from being dead-code eliminated. |
+/// This is useful in a variety of lowering situations. The FakeUse instruction |
+/// has no dest, so it can itself never be dead-code eliminated. |
class InstFakeUse : public InstHighLevel { |
InstFakeUse() = delete; |
InstFakeUse(const InstFakeUse &) = delete; |
@@ -866,16 +859,15 @@ private: |
InstFakeUse(Cfg *Func, Variable *Src); |
}; |
-/// FakeKill instruction. This "kills" a set of variables by modeling |
-/// a trivial live range at this instruction for each (implicit) |
-/// variable. The primary use is to indicate that scratch registers |
-/// are killed after a call, so that the register allocator won't |
-/// assign a scratch register to a variable whose live range spans a |
-/// call. |
+/// FakeKill instruction. This "kills" a set of variables by modeling a trivial |
+/// live range at this instruction for each (implicit) variable. The primary use |
+/// is to indicate that scratch registers are killed after a call, so that the |
+/// register allocator won't assign a scratch register to a variable whose live |
+/// range spans a call. |
/// |
-/// The FakeKill instruction also holds a pointer to the instruction |
-/// that kills the set of variables, so that if that linked instruction |
-/// gets dead-code eliminated, the FakeKill instruction will as well. |
+/// The FakeKill instruction also holds a pointer to the instruction that kills |
+/// the set of variables, so that if that linked instruction gets dead-code |
+/// eliminated, the FakeKill instruction will as well. |
class InstFakeKill : public InstHighLevel { |
InstFakeKill() = delete; |
InstFakeKill(const InstFakeKill &) = delete; |
@@ -898,10 +890,9 @@ private: |
const Inst *Linked; |
}; |
-/// JumpTable instruction. This represents a jump table that will be |
-/// stored in the .rodata section. This is used to track and repoint |
-/// the target CfgNodes which may change, for example due to |
-/// splitting for phi lowering. |
+/// JumpTable instruction. This represents a jump table that will be stored in |
+/// the .rodata section. This is used to track and repoint the target CfgNodes |
+/// which may change, for example due to splitting for phi lowering. |
class InstJumpTable : public InstHighLevel { |
InstJumpTable() = delete; |
InstJumpTable(const InstJumpTable &) = delete; |
@@ -968,8 +959,8 @@ bool checkForRedundantAssign(const Variable *Dest, const Operand *Source); |
namespace llvm { |
-/// Override the default ilist traits so that Inst's private ctor and |
-/// deleted dtor aren't invoked. |
+/// Override the default ilist traits so that Inst's private ctor and deleted |
+/// dtor aren't invoked. |
template <> |
struct ilist_traits<Ice::Inst> : public ilist_default_traits<Ice::Inst> { |
Ice::Inst *createSentinel() const { |