llvm.org GIT mirror llvm / aaa3fa6
Rename NumOperands to make it clear its managed by the User. NFC. This is to try make it very clear that subclasses shouldn't be changing the value directly. Now that OperandList for normal instructions is computed using the NumOperands, its critical that the NumOperands is accurate or we could compute the wrong offset to the first operand. I looked over all places which update NumOperands and they are all safe. Hung off use User's don't use NumOperands to compute the OperandList so they are safe to continue to manipulate it. The only other User which changed it was GlobalVariable which has an optional init list but always allocated space for a single Use. It was correctly setting NumOperands to 1 before setting an initializer, and setting it to 0 after clearing the init list, so the order was safe. Added some comments to that code to make sure that this isn't changed in future without being aware of this constraint. Reviewed by Duncan Exon Smith. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239621 91177308-0d34-0410-b5e6-96231b3b80d8 Pete Cooper 4 years ago
8 changed file(s) with 78 addition(s) and 40 deletion(s). Raw diff Collapse all Expand all
6666 bool isExternallyInitialized = false);
6767
6868 ~GlobalVariable() override {
69 NumOperands = 1; // FIXME: needed by operator delete
69 // FIXME: needed by operator delete
70 setGlobalVariableNumOperands(1);
7071 }
7172
7273 /// Provide fast operand accessors
23492349 assert(BB && "PHI node got a null basic block!");
23502350 assert(getType() == V->getType() &&
23512351 "All operands to PHI node must be the same type as the PHI node!");
2352 if (NumOperands == ReservedSpace)
2352 if (getNumOperands() == ReservedSpace)
23532353 growOperands(); // Get more space!
23542354 // Initialize some new operands.
2355 ++NumOperands;
2356 setIncomingValue(NumOperands - 1, V);
2357 setIncomingBlock(NumOperands - 1, BB);
2355 setNumHungOffUseOperands(getNumOperands() + 1);
2356 setIncomingValue(getNumOperands() - 1, V);
2357 setIncomingBlock(getNumOperands() - 1, BB);
23582358 }
23592359
23602360 /// removeIncomingValue - Remove an incoming value. This is useful if a
5252 User(Type *ty, unsigned vty, Use *OpList, unsigned NumOps)
5353 : Value(ty, vty) {
5454 setOperandList(OpList);
55 NumOperands = NumOps;
55 assert(NumOps < (1u << NumUserOperandsBits) && "Too many operands");
56 NumUserOperands = NumOps;
5657 }
5758
5859 /// \brief Allocate the array of Uses, followed by a pointer
6869 public:
6970 ~User() override {
7071 // drop the hung off uses.
71 Use::zap(getOperandList(), getOperandList() + NumOperands, HasHungOffUses);
72 Use::zap(getOperandList(), getOperandList() + NumUserOperands,
73 HasHungOffUses);
7274 if (HasHungOffUses) {
7375 setOperandList(nullptr);
7476 // Reset NumOperands so User::operator delete() does the right thing.
75 NumOperands = 0;
77 NumUserOperands = 0;
7678 }
7779 }
7880 /// \brief Free memory allocated for User and Use objects.
106108 return LegacyOperandList;
107109 }
108110 Value *getOperand(unsigned i) const {
109 assert(i < NumOperands && "getOperand() out of range!");
111 assert(i < NumUserOperands && "getOperand() out of range!");
110112 return getOperandList()[i];
111113 }
112114 void setOperand(unsigned i, Value *Val) {
113 assert(i < NumOperands && "setOperand() out of range!");
115 assert(i < NumUserOperands && "setOperand() out of range!");
114116 assert((!isa((const Value*)this) ||
115117 isa((const Value*)this)) &&
116118 "Cannot mutate a constant with setOperand!");
117119 getOperandList()[i] = Val;
118120 }
119121 const Use &getOperandUse(unsigned i) const {
120 assert(i < NumOperands && "getOperandUse() out of range!");
122 assert(i < NumUserOperands && "getOperandUse() out of range!");
121123 return getOperandList()[i];
122124 }
123125 Use &getOperandUse(unsigned i) {
124 assert(i < NumOperands && "getOperandUse() out of range!");
126 assert(i < NumUserOperands && "getOperandUse() out of range!");
125127 return getOperandList()[i];
126128 }
127129
128 unsigned getNumOperands() const { return NumOperands; }
130 unsigned getNumOperands() const { return NumUserOperands; }
131
132 /// Set the number of operands on a GlobalVariable.
133 ///
134 /// GlobalVariable always allocates space for a single operands, but
135 /// doesn't always use it.
136 ///
137 /// FIXME: As that the number of operands is used to find the start of
138 /// the allocated memory in operator delete, we need to always think we have
139 /// 1 operand before delete.
140 void setGlobalVariableNumOperands(unsigned NumOps) {
141 assert(NumOps <= 1 && "GlobalVariable can only have 0 or 1 operands");
142 NumUserOperands = NumOps;
143 }
144
145 /// \brief Subclasses with hung off uses need to manage the operand count
146 /// themselves. In these instances, the operand count isn't used to find the
147 /// OperandList, so there's no issue in having the operand count change.
148 void setNumHungOffUseOperands(unsigned NumOps) {
149 assert(HasHungOffUses && "Must have hung off uses to use this method");
150 assert(NumOps < (1u << NumUserOperandsBits) && "Too many operands");
151 NumUserOperands = NumOps;
152 }
129153
130154 // ---------------------------------------------------------------------------
131155 // Operand Iterator interface...
138162 inline op_iterator op_begin() { return getOperandList(); }
139163 inline const_op_iterator op_begin() const { return getOperandList(); }
140164 inline op_iterator op_end() {
141 return getOperandList() + NumOperands;
165 return getOperandList() + NumUserOperands;
142166 }
143167 inline const_op_iterator op_end() const {
144 return getOperandList() + NumOperands;
168 return getOperandList() + NumUserOperands;
145169 }
146170 inline op_range operands() {
147171 return op_range(op_begin(), op_end());
9999 /// This is stored here to save space in User on 64-bit hosts. Since most
100100 /// instances of Value have operands, 32-bit hosts aren't significantly
101101 /// affected.
102 unsigned NumOperands : 29;
102 ///
103 /// Note, this should *NOT* be used directly by any class other than User.
104 /// User uses this value to find the Use list.
105 static const unsigned NumUserOperandsBits = 29;
106 unsigned NumUserOperands : 29;
103107
104108 bool IsUsedByMD : 1;
105109 bool HasName : 1;
213213 void GlobalVariable::setInitializer(Constant *InitVal) {
214214 if (!InitVal) {
215215 if (hasInitializer()) {
216 // Note, the num operands is used to compute the offset of the operand, so
217 // the order here matters. Clearing the operand then clearing the num
218 // operands ensures we have the correct offset to the operand.
216219 Op<0>().set(nullptr);
217 NumOperands = 0;
220 setGlobalVariableNumOperands(0);
218221 }
219222 } else {
220223 assert(InitVal->getType() == getType()->getElementType() &&
221224 "Initializer type must match GlobalVariable type");
225 // Note, the num operands is used to compute the offset of the operand, so
226 // the order here matters. We need to set num operands to 1 first so that
227 // we get the correct offset to the first operand when we set it.
222228 if (!hasInitializer())
223 NumOperands = 1;
229 setGlobalVariableNumOperands(1);
224230 Op<0>().set(InitVal);
225231 }
226232 }
107107
108108 // Nuke the last value.
109109 Op<-1>().set(nullptr);
110 --NumOperands;
110 setNumHungOffUseOperands(getNumOperands() - 1);
111111
112112 // If the PHI node is dead, because it has zero entries, nuke it now.
113113 if (getNumOperands() == 0 && DeletePHIIfEmpty) {
198198 void LandingPadInst::init(Value *PersFn, unsigned NumReservedValues,
199199 const Twine &NameStr) {
200200 ReservedSpace = NumReservedValues;
201 NumOperands = 1;
201 setNumHungOffUseOperands(1);
202202 allocHungoffUses(ReservedSpace);
203203 Op<0>() = PersFn;
204204 setName(NameStr);
218218 unsigned OpNo = getNumOperands();
219219 growOperands(1);
220220 assert(OpNo < ReservedSpace && "Growing didn't work!");
221 ++NumOperands;
221 setNumHungOffUseOperands(getNumOperands() + 1);
222222 getOperandList()[OpNo] = Val;
223223 }
224224
232232 void CallInst::init(FunctionType *FTy, Value *Func, ArrayRef Args,
233233 const Twine &NameStr) {
234234 this->FTy = FTy;
235 assert(NumOperands == Args.size() + 1 && "NumOperands not set up?");
235 assert(getNumOperands() == Args.size() + 1 && "NumOperands not set up?");
236236 Op<-1>() = Func;
237237
238238 #ifndef NDEBUG
253253 void CallInst::init(Value *Func, const Twine &NameStr) {
254254 FTy =
255255 cast(cast(Func->getType())->getElementType());
256 assert(NumOperands == 1 && "NumOperands not set up?");
256 assert(getNumOperands() == 1 && "NumOperands not set up?");
257257 Op<-1>() = Func;
258258
259259 assert(FTy->getNumParams() == 0 && "Calling a function with bad signature");
508508 const Twine &NameStr) {
509509 this->FTy = FTy;
510510
511 assert(NumOperands == 3 + Args.size() && "NumOperands not set up?");
511 assert(getNumOperands() == 3 + Args.size() && "NumOperands not set up?");
512512 Op<-3>() = Fn;
513513 Op<-2>() = IfNormal;
514514 Op<-1>() = IfException;
12041204
12051205 void GetElementPtrInst::init(Value *Ptr, ArrayRef IdxList,
12061206 const Twine &Name) {
1207 assert(NumOperands == 1 + IdxList.size() && "NumOperands not initialized?");
1207 assert(getNumOperands() == 1 + IdxList.size() &&
1208 "NumOperands not initialized?");
12081209 Op<0>() = Ptr;
12091210 std::copy(IdxList.begin(), IdxList.end(), op_begin() + 1);
12101211 setName(Name);
15171518
15181519 void InsertValueInst::init(Value *Agg, Value *Val, ArrayRef Idxs,
15191520 const Twine &Name) {
1520 assert(NumOperands == 2 && "NumOperands not initialized?");
1521 assert(getNumOperands() == 2 && "NumOperands not initialized?");
15211522
15221523 // There's no fundamental reason why we require at least one index
15231524 // (other than weirdness with &*IdxBegin being invalid; see
15481549 //===----------------------------------------------------------------------===//
15491550
15501551 void ExtractValueInst::init(ArrayRef Idxs, const Twine &Name) {
1551 assert(NumOperands == 1 && "NumOperands not initialized?");
1552 assert(getNumOperands() == 1 && "NumOperands not initialized?");
15521553
15531554 // There's no fundamental reason why we require at least one index.
15541555 // But there's no present need to support it.
32623263 void SwitchInst::init(Value *Value, BasicBlock *Default, unsigned NumReserved) {
32633264 assert(Value && Default && NumReserved);
32643265 ReservedSpace = NumReserved;
3265 NumOperands = 2;
3266 setNumHungOffUseOperands(2);
32663267 allocHungoffUses(ReservedSpace);
32673268
32683269 Op<0>() = Value;
32943295 SwitchInst::SwitchInst(const SwitchInst &SI)
32953296 : TerminatorInst(SI.getType(), Instruction::Switch, nullptr, 0) {
32963297 init(SI.getCondition(), SI.getDefaultDest(), SI.getNumOperands());
3297 NumOperands = SI.getNumOperands();
3298 setNumHungOffUseOperands(SI.getNumOperands());
32983299 Use *OL = getOperandList();
32993300 const Use *InOL = SI.getOperandList();
33003301 for (unsigned i = 2, E = SI.getNumOperands(); i != E; i += 2) {
33083309 /// addCase - Add an entry to the switch instruction...
33093310 ///
33103311 void SwitchInst::addCase(ConstantInt *OnVal, BasicBlock *Dest) {
3311 unsigned NewCaseIdx = getNumCases();
3312 unsigned OpNo = NumOperands;
3312 unsigned NewCaseIdx = getNumCases();
3313 unsigned OpNo = getNumOperands();
33133314 if (OpNo+2 > ReservedSpace)
33143315 growOperands(); // Get more space!
33153316 // Initialize some new operands.
33163317 assert(OpNo+1 < ReservedSpace && "Growing didn't work!");
3317 NumOperands = OpNo+2;
3318 setNumHungOffUseOperands(OpNo+2);
33183319 CaseIt Case(this, NewCaseIdx);
33193320 Case.setValue(OnVal);
33203321 Case.setSuccessor(Dest);
33393340 // Nuke the last value.
33403341 OL[NumOps-2].set(nullptr);
33413342 OL[NumOps-2+1].set(nullptr);
3342 NumOperands = NumOps-2;
3343 setNumHungOffUseOperands(NumOps-2);
33433344 }
33443345
33453346 /// growOperands - grow operands - This grows the operand list in response
33723373 assert(Address && Address->getType()->isPointerTy() &&
33733374 "Address of indirectbr must be a pointer");
33743375 ReservedSpace = 1+NumDests;
3375 NumOperands = 1;
3376 setNumHungOffUseOperands(1);
33763377 allocHungoffUses(ReservedSpace);
33773378
33783379 Op<0>() = Address;
34183419 /// addDestination - Add a destination.
34193420 ///
34203421 void IndirectBrInst::addDestination(BasicBlock *DestBB) {
3421 unsigned OpNo = NumOperands;
3422 unsigned OpNo = getNumOperands();
34223423 if (OpNo+1 > ReservedSpace)
34233424 growOperands(); // Get more space!
34243425 // Initialize some new operands.
34253426 assert(OpNo < ReservedSpace && "Growing didn't work!");
3426 NumOperands = OpNo+1;
3427 setNumHungOffUseOperands(OpNo+1);
34273428 getOperandList()[OpNo] = DestBB;
34283429 }
34293430
34403441
34413442 // Nuke the last value.
34423443 OL[NumOps-1].set(nullptr);
3443 NumOperands = NumOps-1;
3444 setNumHungOffUseOperands(NumOps-1);
34443445 }
34453446
34463447 BasicBlock *IndirectBrInst::getSuccessorV(unsigned idx) const {
8585 //===----------------------------------------------------------------------===//
8686
8787 void *User::operator new(size_t s, unsigned Us) {
88 assert(Us < (1u << NumUserOperandsBits) && "Too many operands");
8889 void *Storage = ::operator new(s + sizeof(Use) * Us);
8990 Use *Start = static_cast(Storage);
9091 Use *End = Start + Us;
9192 User *Obj = reinterpret_cast(End);
9293 Obj->setOperandList(Start);
9394 Obj->HasHungOffUses = false;
94 Obj->NumOperands = Us;
95 Obj->NumUserOperands = Us;
9596 Use::initTags(Start, End);
9697 return Obj;
9798 }
102103
103104 void User::operator delete(void *Usr) {
104105 User *Start = static_cast(Usr);
105 Use *Storage = static_cast(Usr) - Start->NumOperands;
106 Use *Storage = static_cast(Usr) - Start->NumUserOperands;
106107 // If there were hung-off uses, they will have been freed already and
107108 // NumOperands reset to 0, so here we just free the User itself.
108109 ::operator delete(Storage);
3838 //===----------------------------------------------------------------------===//
3939 // Value Class
4040 //===----------------------------------------------------------------------===//
41 const unsigned Value::NumUserOperandsBits;
4142
4243 static inline Type *checkType(Type *Ty) {
4344 assert(Ty && "Value defined with a null type: Error!");
4748 Value::Value(Type *ty, unsigned scid)
4849 : VTy(checkType(ty)), UseList(nullptr), SubclassID(scid),
4950 HasValueHandle(0), SubclassOptionalData(0), SubclassData(0),
50 NumOperands(0), IsUsedByMD(false), HasName(false) {
51 NumUserOperands(0), IsUsedByMD(false), HasName(false) {
5152 // FIXME: Why isn't this in the subclass gunk??
5253 // Note, we cannot call isa before the CallInst has been
5354 // constructed.