@@ -142,12 +142,20 @@ class LoadInst : public UnaryInstruction {
142142 LoadInst (Value *Ptr, const Twine &NameStr, BasicBlock *InsertAtEnd);
143143 LoadInst (Value *Ptr, const Twine &NameStr, bool isVolatile = false ,
144144 Instruction *InsertBefore = 0 );
145- LoadInst (Value *Ptr, const Twine &NameStr, bool isVolatile,
146- unsigned Align, Instruction *InsertBefore = 0 );
147145 LoadInst (Value *Ptr, const Twine &NameStr, bool isVolatile,
148146 BasicBlock *InsertAtEnd);
147+ LoadInst (Value *Ptr, const Twine &NameStr, bool isVolatile,
148+ unsigned Align, Instruction *InsertBefore = 0 );
149149 LoadInst (Value *Ptr, const Twine &NameStr, bool isVolatile,
150150 unsigned Align, BasicBlock *InsertAtEnd);
151+ LoadInst (Value *Ptr, const Twine &NameStr, bool isVolatile,
152+ unsigned Align, AtomicOrdering Order,
153+ SynchronizationScope SynchScope = CrossThread,
154+ Instruction *InsertBefore = 0 );
155+ LoadInst (Value *Ptr, const Twine &NameStr, bool isVolatile,
156+ unsigned Align, AtomicOrdering Order,
157+ SynchronizationScope SynchScope,
158+ BasicBlock *InsertAtEnd);
151159
152160 LoadInst (Value *Ptr, const char *NameStr, Instruction *InsertBefore);
153161 LoadInst (Value *Ptr, const char *NameStr, BasicBlock *InsertAtEnd);
@@ -171,11 +179,47 @@ class LoadInst : public UnaryInstruction {
171179 // / getAlignment - Return the alignment of the access that is being performed
172180 // /
173181 unsigned getAlignment () const {
174- return (1 << (getSubclassDataFromInstruction () >> 1 )) >> 1 ;
182+ return (1 << (( getSubclassDataFromInstruction () >> 1 ) & 31 )) >> 1 ;
175183 }
176184
177185 void setAlignment (unsigned Align);
178186
187+ // / Returns the ordering effect of this fence.
188+ AtomicOrdering getOrdering () const {
189+ return AtomicOrdering ((getSubclassDataFromInstruction () >> 7 ) & 7 );
190+ }
191+
192+ // / Set the ordering constraint on this load. May not be Release or
193+ // / AcquireRelease.
194+ void setOrdering (AtomicOrdering Ordering) {
195+ setInstructionSubclassData ((getSubclassDataFromInstruction () & ~(7 << 7 )) |
196+ (Ordering << 7 ));
197+ }
198+
199+ SynchronizationScope getSynchScope () const {
200+ return SynchronizationScope ((getSubclassDataFromInstruction () >> 6 ) & 1 );
201+ }
202+
203+ // / Specify whether this load is ordered with respect to all
204+ // / concurrently executing threads, or only with respect to signal handlers
205+ // / executing in the same thread.
206+ void setSynchScope (SynchronizationScope xthread) {
207+ setInstructionSubclassData ((getSubclassDataFromInstruction () & ~(1 << 6 )) |
208+ (xthread << 6 ));
209+ }
210+
211+ bool isAtomic () const { return getOrdering () != NotAtomic; }
212+ void setAtomic (AtomicOrdering Ordering,
213+ SynchronizationScope SynchScope = CrossThread) {
214+ setOrdering (Ordering);
215+ setSynchScope (SynchScope);
216+ }
217+
218+ bool isSimple () const { return !isAtomic () && !isVolatile (); }
219+ bool isUnordered () const {
220+ return getOrdering () <= Unordered && !isVolatile ();
221+ }
222+
179223 Value *getPointerOperand () { return getOperand (0 ); }
180224 const Value *getPointerOperand () const { return getOperand (0 ); }
181225 static unsigned getPointerOperandIndex () { return 0U ; }
@@ -222,19 +266,27 @@ class StoreInst : public Instruction {
222266 StoreInst (Value *Val, Value *Ptr, BasicBlock *InsertAtEnd);
223267 StoreInst (Value *Val, Value *Ptr, bool isVolatile = false ,
224268 Instruction *InsertBefore = 0 );
269+ StoreInst (Value *Val, Value *Ptr, bool isVolatile, BasicBlock *InsertAtEnd);
225270 StoreInst (Value *Val, Value *Ptr, bool isVolatile,
226271 unsigned Align, Instruction *InsertBefore = 0 );
227- StoreInst (Value *Val, Value *Ptr, bool isVolatile, BasicBlock *InsertAtEnd);
228272 StoreInst (Value *Val, Value *Ptr, bool isVolatile,
229273 unsigned Align, BasicBlock *InsertAtEnd);
274+ StoreInst (Value *Val, Value *Ptr, bool isVolatile,
275+ unsigned Align, AtomicOrdering Order,
276+ SynchronizationScope SynchScope = CrossThread,
277+ Instruction *InsertBefore = 0 );
278+ StoreInst (Value *Val, Value *Ptr, bool isVolatile,
279+ unsigned Align, AtomicOrdering Order,
280+ SynchronizationScope SynchScope,
281+ BasicBlock *InsertAtEnd);
282+
230283
231-
232- // / isVolatile - Return true if this is a load from a volatile memory
284+ // / isVolatile - Return true if this is a store to a volatile memory
233285 // / location.
234286 // /
235287 bool isVolatile () const { return getSubclassDataFromInstruction () & 1 ; }
236288
237- // / setVolatile - Specify whether this is a volatile load or not.
289+ // / setVolatile - Specify whether this is a volatile store or not.
238290 // /
239291 void setVolatile (bool V) {
240292 setInstructionSubclassData ((getSubclassDataFromInstruction () & ~1 ) |
@@ -247,11 +299,47 @@ class StoreInst : public Instruction {
247299 // / getAlignment - Return the alignment of the access that is being performed
248300 // /
249301 unsigned getAlignment () const {
250- return (1 << (getSubclassDataFromInstruction () >> 1 )) >> 1 ;
302+ return (1 << (( getSubclassDataFromInstruction () >> 1 ) & 31 )) >> 1 ;
251303 }
252304
253305 void setAlignment (unsigned Align);
254306
307+ // / Returns the ordering effect of this store.
308+ AtomicOrdering getOrdering () const {
309+ return AtomicOrdering ((getSubclassDataFromInstruction () >> 7 ) & 7 );
310+ }
311+
312+ // / Set the ordering constraint on this store. May not be Acquire or
313+ // / AcquireRelease.
314+ void setOrdering (AtomicOrdering Ordering) {
315+ setInstructionSubclassData ((getSubclassDataFromInstruction () & ~(7 << 7 )) |
316+ (Ordering << 7 ));
317+ }
318+
319+ SynchronizationScope getSynchScope () const {
320+ return SynchronizationScope ((getSubclassDataFromInstruction () >> 6 ) & 1 );
321+ }
322+
323+ // / Specify whether this store instruction is ordered with respect to all
324+ // / concurrently executing threads, or only with respect to signal handlers
325+ // / executing in the same thread.
326+ void setSynchScope (SynchronizationScope xthread) {
327+ setInstructionSubclassData ((getSubclassDataFromInstruction () & ~(1 << 6 )) |
328+ (xthread << 6 ));
329+ }
330+
331+ bool isAtomic () const { return getOrdering () != NotAtomic; }
332+ void setAtomic (AtomicOrdering Ordering,
333+ SynchronizationScope SynchScope = CrossThread) {
334+ setOrdering (Ordering);
335+ setSynchScope (SynchScope);
336+ }
337+
338+ bool isSimple () const { return !isAtomic () && !isVolatile (); }
339+ bool isUnordered () const {
340+ return getOrdering () <= Unordered && !isVolatile ();
341+ }
342+
255343 Value *getValueOperand () { return getOperand (0 ); }
256344 const Value *getValueOperand () const { return getOperand (0 ); }
257345
@@ -319,18 +407,8 @@ class FenceInst : public Instruction {
319407 // / Set the ordering constraint on this fence. May only be Acquire, Release,
320408 // / AcquireRelease, or SequentiallyConsistent.
321409 void setOrdering (AtomicOrdering Ordering) {
322- switch (Ordering) {
323- case Acquire:
324- case Release:
325- case AcquireRelease:
326- case SequentiallyConsistent:
327- setInstructionSubclassData ((getSubclassDataFromInstruction () & 1 ) |
328- (Ordering << 1 ));
329- return ;
330- default :
331- llvm_unreachable (" FenceInst ordering must be Acquire, Release,"
332- " AcquireRelease, or SequentiallyConsistent" );
333- }
410+ setInstructionSubclassData ((getSubclassDataFromInstruction () & 1 ) |
411+ (Ordering << 1 ));
334412 }
335413
336414 SynchronizationScope getSynchScope () const {
@@ -555,7 +633,7 @@ class AtomicRMWInst : public Instruction {
555633 void setOrdering (AtomicOrdering Ordering) {
556634 assert (Ordering != NotAtomic &&
557635 " atomicrmw instructions can only be atomic." );
558- setInstructionSubclassData ((getSubclassDataFromInstruction () & ~28 ) |
636+ setInstructionSubclassData ((getSubclassDataFromInstruction () & ~( 7 << 2 ) ) |
559637 (Ordering << 2 ));
560638 }
561639
@@ -569,7 +647,7 @@ class AtomicRMWInst : public Instruction {
569647
570648 // / Returns the ordering constraint on this RMW.
571649 AtomicOrdering getOrdering () const {
572- return AtomicOrdering ((getSubclassDataFromInstruction () & 28 ) >> 2 );
650+ return AtomicOrdering ((getSubclassDataFromInstruction () >> 2 ) & 7 );
573651 }
574652
575653 // / Returns whether this RMW is atomic between threads or only within a
0 commit comments