Index: src/IceOperand.h |
diff --git a/src/IceOperand.h b/src/IceOperand.h |
index fd688348f79c4075fe64cc8c23c3b9c6026a491a..709ab9787c842e8c4c2025530f56151cebd435fb 100644 |
--- a/src/IceOperand.h |
+++ b/src/IceOperand.h |
@@ -52,6 +52,7 @@ public: |
kConst_Max = kConst_Target + MaxTargetKinds, |
kVariable, |
kVariable64On32, |
+ kVariableVecOn32, |
kVariableBoolean, |
kVariable_Target, // leave space for target-specific variable kinds |
kVariable_Max = kVariable_Target + MaxTargetKinds, |
@@ -962,6 +963,94 @@ protected: |
Variable *HiVar = nullptr; |
}; |
+// VariableVecOn32 represents a vectory variable on a 32-bit architecture. In |
Jim Stichnoth
2016/09/29 16:50:25
s/vectory/vector/
jaydeep.patil
2016/09/30 07:02:51
Done.
|
+// this situation the variable must be split into 4 containers. |
+class VariableVecOn32 : public Variable { |
+ VariableVecOn32() = delete; |
+ VariableVecOn32(const VariableVecOn32 &) = delete; |
+ VariableVecOn32 &operator=(const VariableVecOn32 &) = delete; |
+ |
+public: |
+ static VariableVecOn32 *create(Cfg *Func, Type Ty, SizeT Index) { |
+ return new (Func->allocate<VariableVecOn32>()) |
+ VariableVecOn32(Func, kVariableVecOn32, Ty, Index); |
+ } |
+ |
+ void setName(const Cfg *Func, const std::string &NewName) override { |
+ Variable::setName(Func, NewName); |
+ if (Containers.size()) { |
Jim Stichnoth
2016/09/29 16:50:25
!Containers.empty()
here and below.
empty() shou
jaydeep.patil
2016/09/30 07:02:51
Done.
|
+ for (size_t I = 0; I < NumContainers; I++) { |
Jim Stichnoth
2016/09/29 16:50:25
We usually prefer pre-incement (++I), as ugly as t
jaydeep.patil
2016/09/30 07:02:51
Done.
|
+ Containers[I]->setName(Func, getName() + "__cont" + std::to_string(I)); |
+ } |
+ } |
+ } |
+ |
+ void setIsArg(bool Val = true) override { |
+ Variable::setIsArg(Val); |
+ if (Containers.size()) { |
+ for (size_t I = 0; I < NumContainers; I++) { |
Jim Stichnoth
2016/09/29 16:50:25
for (Variable &Var : Containers) {
Var.setName(.
jaydeep.patil
2016/09/30 07:02:51
Done.
|
+ Containers[I]->setIsArg(getIsArg()); |
+ } |
+ } |
+ } |
+ |
+ Variable *getVecElementAtIndex(uint32_t Index) { |
+ assert(Index < NumElements); |
+ if (Containers.size()) { |
+ return Containers[Index / (NumElements / NumContainers)]; |
+ } |
+ return nullptr; |
+ } |
+ |
+ Variable *getContainerAtIndex(uint32_t Index) { |
+ assert(Index < NumContainers); |
+ if (Containers.size()) { |
+ return Containers[Index]; |
+ } |
+ return nullptr; |
+ } |
+ |
+ size_t getNumContainers() { return NumContainers; } |
Jim Stichnoth
2016/09/29 16:50:25
mark all these getters as const
jaydeep.patil
2016/09/30 07:02:51
Done.
|
+ size_t getNumElements() { return NumElements; } |
+ Type getElementType() { return ElementType; } |
+ Type getContainerType() { return ContainerType; } |
+ |
+ void initVecElement(Cfg *Func, Type VecType) { |
+ NumElements = typeNumElements(VecType); |
+ ElementType = typeElementType(VecType); |
+ // Specific to MIPS32R1 |
+ ContainerType = IceType_i32; |
+ NumContainers = typeWidthInBytes(ContainerType); |
+ for (size_t I = 0; I < NumContainers; I++) { |
+ Variable *Var = Func->makeVariable(ContainerType); |
+ Var->setIsArg(getIsArg()); |
+ if (BuildDefs::dump()) { |
+ Var->setName(Func, getName() + "__cont" + std::to_string(I)); |
+ } |
+ Containers.push_back(Var); |
+ } |
+ } |
+ |
+ static bool classof(const Operand *Operand) { |
+ OperandKind Kind = Operand->getKind(); |
+ return Kind == kVariableVecOn32; |
+ } |
+ |
+protected: |
+ VariableVecOn32(const Cfg *Func, OperandKind K, Type Ty, SizeT Index) |
+ : Variable(Func, K, Ty, Index) { |
+ assert(typeWidthInBytes(Ty) == 16); |
+ } |
+ |
+ // Number of elements in this vector (4 to 16). |
+ size_t NumElements = 0; |
Jim Stichnoth
2016/09/29 16:50:25
In the interest of keeping this data structure sma
jaydeep.patil
2016/09/30 07:02:51
Done.
|
+ VarList Containers; |
+ Type ElementType; |
+ // Number of physical registers used to hold this vector. |
+ size_t NumContainers; |
Jim Stichnoth
2016/09/29 16:50:25
Can you remove this field, since it is redundant w
jaydeep.patil
2016/09/30 07:02:51
Done.
|
+ Type ContainerType; |
+}; |
+ |
enum MetadataKind { |
VMK_Uses, /// Track only uses, not defs |
VMK_SingleDefs, /// Track uses+defs, but only record single def |