Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit 9423112

Browse files
committed
Merging r309651 and r309849:
------------------------------------------------------------------------ r309651 | inouehrs | 2017-07-31 20:32:15 -0700 (Mon, 31 Jul 2017) | 16 lines [StackColoring] Update AliasAnalysis information in stack coloring pass Stack coloring pass need to maintain AliasAnalysis information when merging stack slots of different types. Actually, there is a FIXME comment in StackColoring.cpp // FIXME: In order to enable the use of TBAA when using AA in CodeGen, // we'll also need to update the TBAA nodes in MMOs with values // derived from the merged allocas. But, TBAA has been already enabled in CodeGen without fixing this pass. The incorrect TBAA metadata results in recent failures in bootstrap test on ppc64le (PR33928) by allowing unsafe instruction scheduling. Although we observed the problem on ppc64le, this is a platform neutral issue. This patch makes the stack coloring pass maintains AliasAnalysis information when merging multiple stack slots. ------------------------------------------------------------------------ ------------------------------------------------------------------------ r309849 | inouehrs | 2017-08-02 11:16:32 -0700 (Wed, 02 Aug 2017) | 19 lines [StackColoring] Update AliasAnalysis information in stack coloring pass (part 2) This patch is update after the first patch (https://reviews.llvm.org/rL309651) based on the post-commit comments. Stack coloring pass need to maintain AliasAnalysis information when merging stack slots of different types. Actually, there is a FIXME comment in StackColoring.cpp // FIXME: In order to enable the use of TBAA when using AA in CodeGen, // we'll also need to update the TBAA nodes in MMOs with values // derived from the merged allocas. But, TBAA has been already enabled in CodeGen without fixing this pass. The incorrect TBAA metadata results in recent failures in bootstrap test on ppc64le (PR33928) by allowing unsafe instruction scheduling. Although we observed the problem on ppc64le, this is a platform neutral issue. This patch makes the stack coloring pass maintains AliasAnalysis information when merging multiple stack slots. This patch fixes PR33928. ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_50@309957 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent f632da1 commit 9423112

File tree

7 files changed

+145
-68
lines changed

7 files changed

+145
-68
lines changed

include/llvm/Analysis/ValueTracking.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,12 @@ template <typename T> class ArrayRef;
312312
const DataLayout &DL, LoopInfo *LI = nullptr,
313313
unsigned MaxLookup = 6);
314314

315+
/// This is a wrapper around GetUnderlyingObjects and adds support for basic
316+
/// ptrtoint+arithmetic+inttoptr sequences.
317+
void getUnderlyingObjectsForCodeGen(const Value *V,
318+
SmallVectorImpl<Value *> &Objects,
319+
const DataLayout &DL);
320+
315321
/// Return true if the only users of this pointer are lifetime markers.
316322
bool onlyUsedByLifetimeMarkers(const Value *V);
317323

include/llvm/CodeGen/MachineFunction.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,12 @@ class MachineFunction {
661661
MachineMemOperand *getMachineMemOperand(const MachineMemOperand *MMO,
662662
int64_t Offset, uint64_t Size);
663663

664+
/// Allocate a new MachineMemOperand by copying an existing one,
665+
/// replacing only AliasAnalysis information. MachineMemOperands are owned
666+
/// by the MachineFunction and need not be explicitly deallocated.
667+
MachineMemOperand *getMachineMemOperand(const MachineMemOperand *MMO,
668+
const AAMDNodes &AAInfo);
669+
664670
using OperandCapacity = ArrayRecycler<MachineOperand>::Capacity;
665671

666672
/// Allocate an array of MachineOperands. This is only intended for use by

include/llvm/CodeGen/MachineInstr.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,9 @@ class MachineInstr
379379
return NumMemRefs == 1;
380380
}
381381

382+
/// Return the number of memory operands.
383+
unsigned getNumMemOperands() const { return NumMemRefs; }
384+
382385
/// API for querying MachineInstr properties. They are the same as MCInstrDesc
383386
/// queries but they are bundle aware.
384387

lib/Analysis/ValueTracking.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3277,6 +3277,69 @@ void llvm::GetUnderlyingObjects(Value *V, SmallVectorImpl<Value *> &Objects,
32773277
} while (!Worklist.empty());
32783278
}
32793279

3280+
/// This is the function that does the work of looking through basic
3281+
/// ptrtoint+arithmetic+inttoptr sequences.
3282+
static const Value *getUnderlyingObjectFromInt(const Value *V) {
3283+
do {
3284+
if (const Operator *U = dyn_cast<Operator>(V)) {
3285+
// If we find a ptrtoint, we can transfer control back to the
3286+
// regular getUnderlyingObjectFromInt.
3287+
if (U->getOpcode() == Instruction::PtrToInt)
3288+
return U->getOperand(0);
3289+
// If we find an add of a constant, a multiplied value, or a phi, it's
3290+
// likely that the other operand will lead us to the base
3291+
// object. We don't have to worry about the case where the
3292+
// object address is somehow being computed by the multiply,
3293+
// because our callers only care when the result is an
3294+
// identifiable object.
3295+
if (U->getOpcode() != Instruction::Add ||
3296+
(!isa<ConstantInt>(U->getOperand(1)) &&
3297+
Operator::getOpcode(U->getOperand(1)) != Instruction::Mul &&
3298+
!isa<PHINode>(U->getOperand(1))))
3299+
return V;
3300+
V = U->getOperand(0);
3301+
} else {
3302+
return V;
3303+
}
3304+
assert(V->getType()->isIntegerTy() && "Unexpected operand type!");
3305+
} while (true);
3306+
}
3307+
3308+
/// This is a wrapper around GetUnderlyingObjects and adds support for basic
3309+
/// ptrtoint+arithmetic+inttoptr sequences.
3310+
void llvm::getUnderlyingObjectsForCodeGen(const Value *V,
3311+
SmallVectorImpl<Value *> &Objects,
3312+
const DataLayout &DL) {
3313+
SmallPtrSet<const Value *, 16> Visited;
3314+
SmallVector<const Value *, 4> Working(1, V);
3315+
do {
3316+
V = Working.pop_back_val();
3317+
3318+
SmallVector<Value *, 4> Objs;
3319+
GetUnderlyingObjects(const_cast<Value *>(V), Objs, DL);
3320+
3321+
for (Value *V : Objs) {
3322+
if (!Visited.insert(V).second)
3323+
continue;
3324+
if (Operator::getOpcode(V) == Instruction::IntToPtr) {
3325+
const Value *O =
3326+
getUnderlyingObjectFromInt(cast<User>(V)->getOperand(0));
3327+
if (O->getType()->isPointerTy()) {
3328+
Working.push_back(O);
3329+
continue;
3330+
}
3331+
}
3332+
// If GetUnderlyingObjects fails to find an identifiable object,
3333+
// getUnderlyingObjectsForCodeGen also fails for safety.
3334+
if (!isIdentifiedObject(V)) {
3335+
Objects.clear();
3336+
return;
3337+
}
3338+
Objects.push_back(const_cast<Value *>(V));
3339+
}
3340+
} while (!Working.empty());
3341+
}
3342+
32803343
/// Return true if the only users of this pointer are lifetime markers.
32813344
bool llvm::onlyUsedByLifetimeMarkers(const Value *V) {
32823345
for (const User *U : V->users()) {

lib/CodeGen/MachineFunction.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,20 @@ MachineFunction::getMachineMemOperand(const MachineMemOperand *MMO,
330330
MMO->getOrdering(), MMO->getFailureOrdering());
331331
}
332332

333+
MachineMemOperand *
334+
MachineFunction::getMachineMemOperand(const MachineMemOperand *MMO,
335+
const AAMDNodes &AAInfo) {
336+
MachinePointerInfo MPI = MMO->getValue() ?
337+
MachinePointerInfo(MMO->getValue(), MMO->getOffset()) :
338+
MachinePointerInfo(MMO->getPseudoValue(), MMO->getOffset());
339+
340+
return new (Allocator)
341+
MachineMemOperand(MPI, MMO->getFlags(), MMO->getSize(),
342+
MMO->getBaseAlignment(), AAInfo,
343+
MMO->getRanges(), MMO->getSyncScopeID(),
344+
MMO->getOrdering(), MMO->getFailureOrdering());
345+
}
346+
333347
MachineInstr::mmo_iterator
334348
MachineFunction::allocateMemRefsArray(unsigned long Num) {
335349
return Allocator.Allocate<MachineMemOperand *>(Num);

lib/CodeGen/ScheduleDAGInstrs.cpp

Lines changed: 2 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -121,63 +121,6 @@ ScheduleDAGInstrs::ScheduleDAGInstrs(MachineFunction &mf,
121121
SchedModel.init(ST.getSchedModel(), &ST, TII);
122122
}
123123

124-
/// This is the function that does the work of looking through basic
125-
/// ptrtoint+arithmetic+inttoptr sequences.
126-
static const Value *getUnderlyingObjectFromInt(const Value *V) {
127-
do {
128-
if (const Operator *U = dyn_cast<Operator>(V)) {
129-
// If we find a ptrtoint, we can transfer control back to the
130-
// regular getUnderlyingObjectFromInt.
131-
if (U->getOpcode() == Instruction::PtrToInt)
132-
return U->getOperand(0);
133-
// If we find an add of a constant, a multiplied value, or a phi, it's
134-
// likely that the other operand will lead us to the base
135-
// object. We don't have to worry about the case where the
136-
// object address is somehow being computed by the multiply,
137-
// because our callers only care when the result is an
138-
// identifiable object.
139-
if (U->getOpcode() != Instruction::Add ||
140-
(!isa<ConstantInt>(U->getOperand(1)) &&
141-
Operator::getOpcode(U->getOperand(1)) != Instruction::Mul &&
142-
!isa<PHINode>(U->getOperand(1))))
143-
return V;
144-
V = U->getOperand(0);
145-
} else {
146-
return V;
147-
}
148-
assert(V->getType()->isIntegerTy() && "Unexpected operand type!");
149-
} while (true);
150-
}
151-
152-
/// This is a wrapper around GetUnderlyingObjects and adds support for basic
153-
/// ptrtoint+arithmetic+inttoptr sequences.
154-
static void getUnderlyingObjects(const Value *V,
155-
SmallVectorImpl<Value *> &Objects,
156-
const DataLayout &DL) {
157-
SmallPtrSet<const Value *, 16> Visited;
158-
SmallVector<const Value *, 4> Working(1, V);
159-
do {
160-
V = Working.pop_back_val();
161-
162-
SmallVector<Value *, 4> Objs;
163-
GetUnderlyingObjects(const_cast<Value *>(V), Objs, DL);
164-
165-
for (Value *V : Objs) {
166-
if (!Visited.insert(V).second)
167-
continue;
168-
if (Operator::getOpcode(V) == Instruction::IntToPtr) {
169-
const Value *O =
170-
getUnderlyingObjectFromInt(cast<User>(V)->getOperand(0));
171-
if (O->getType()->isPointerTy()) {
172-
Working.push_back(O);
173-
continue;
174-
}
175-
}
176-
Objects.push_back(const_cast<Value *>(V));
177-
}
178-
} while (!Working.empty());
179-
}
180-
181124
/// If this machine instr has memory reference information and it can be tracked
182125
/// to a normal reference to a known object, return the Value for that object.
183126
static void getUnderlyingObjectsForInstr(const MachineInstr *MI,
@@ -208,12 +151,10 @@ static void getUnderlyingObjectsForInstr(const MachineInstr *MI,
208151
Objects.push_back(UnderlyingObjectsVector::value_type(PSV, MayAlias));
209152
} else if (const Value *V = MMO->getValue()) {
210153
SmallVector<Value *, 4> Objs;
211-
getUnderlyingObjects(V, Objs, DL);
154+
getUnderlyingObjectsForCodeGen(V, Objs, DL);
212155

213156
for (Value *V : Objs) {
214-
if (!isIdentifiedObject(V))
215-
return false;
216-
157+
assert(isIdentifiedObject(V));
217158
Objects.push_back(UnderlyingObjectsVector::value_type(V, true));
218159
}
219160
} else

lib/CodeGen/StackColoring.cpp

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "llvm/CodeGen/MachineRegisterInfo.h"
3838
#include "llvm/CodeGen/Passes.h"
3939
#include "llvm/CodeGen/PseudoSourceValue.h"
40+
#include "llvm/CodeGen/SelectionDAGNodes.h"
4041
#include "llvm/CodeGen/SlotIndexes.h"
4142
#include "llvm/CodeGen/StackProtector.h"
4243
#include "llvm/CodeGen/WinEHFuncInfo.h"
@@ -889,6 +890,10 @@ void StackColoring::remapInstructions(DenseMap<int, int> &SlotRemap) {
889890

890891
// Keep a list of *allocas* which need to be remapped.
891892
DenseMap<const AllocaInst*, const AllocaInst*> Allocas;
893+
894+
// Keep a list of allocas which has been affected by the remap.
895+
SmallPtrSet<const AllocaInst*, 32> MergedAllocas;
896+
892897
for (const std::pair<int, int> &SI : SlotRemap) {
893898
const AllocaInst *From = MFI->getObjectAllocation(SI.first);
894899
const AllocaInst *To = MFI->getObjectAllocation(SI.second);
@@ -908,6 +913,10 @@ void StackColoring::remapInstructions(DenseMap<int, int> &SlotRemap) {
908913
Inst = Cast;
909914
}
910915

916+
// We keep both slots to maintain AliasAnalysis metadata later.
917+
MergedAllocas.insert(From);
918+
MergedAllocas.insert(To);
919+
911920
// Allow the stack protector to adjust its value map to account for the
912921
// upcoming replacement.
913922
SP->adjustForColoring(From, To);
@@ -939,13 +948,6 @@ void StackColoring::remapInstructions(DenseMap<int, int> &SlotRemap) {
939948

940949
// Update the MachineMemOperand to use the new alloca.
941950
for (MachineMemOperand *MMO : I.memoperands()) {
942-
// FIXME: In order to enable the use of TBAA when using AA in CodeGen,
943-
// we'll also need to update the TBAA nodes in MMOs with values
944-
// derived from the merged allocas. When doing this, we'll need to use
945-
// the same variant of GetUnderlyingObjects that is used by the
946-
// instruction scheduler (that can look through ptrtoint/inttoptr
947-
// pairs).
948-
949951
// We've replaced IR-level uses of the remapped allocas, so we only
950952
// need to replace direct uses here.
951953
const AllocaInst *AI = dyn_cast_or_null<AllocaInst>(MMO->getValue());
@@ -997,6 +999,48 @@ void StackColoring::remapInstructions(DenseMap<int, int> &SlotRemap) {
997999
MO.setIndex(ToSlot);
9981000
FixedInstr++;
9991001
}
1002+
1003+
// We adjust AliasAnalysis information for merged stack slots.
1004+
MachineSDNode::mmo_iterator NewMemOps =
1005+
MF->allocateMemRefsArray(I.getNumMemOperands());
1006+
unsigned MemOpIdx = 0;
1007+
bool ReplaceMemOps = false;
1008+
for (MachineMemOperand *MMO : I.memoperands()) {
1009+
// If this memory location can be a slot remapped here,
1010+
// we remove AA information.
1011+
bool MayHaveConflictingAAMD = false;
1012+
if (MMO->getAAInfo()) {
1013+
if (const Value *MMOV = MMO->getValue()) {
1014+
SmallVector<Value *, 4> Objs;
1015+
getUnderlyingObjectsForCodeGen(MMOV, Objs, MF->getDataLayout());
1016+
1017+
if (Objs.empty())
1018+
MayHaveConflictingAAMD = true;
1019+
else
1020+
for (Value *V : Objs) {
1021+
// If this memory location comes from a known stack slot
1022+
// that is not remapped, we continue checking.
1023+
// Otherwise, we need to invalidate AA infomation.
1024+
const AllocaInst *AI = dyn_cast_or_null<AllocaInst>(V);
1025+
if (AI && MergedAllocas.count(AI)) {
1026+
MayHaveConflictingAAMD = true;
1027+
break;
1028+
}
1029+
}
1030+
}
1031+
}
1032+
if (MayHaveConflictingAAMD) {
1033+
NewMemOps[MemOpIdx++] = MF->getMachineMemOperand(MMO, AAMDNodes());
1034+
ReplaceMemOps = true;
1035+
}
1036+
else
1037+
NewMemOps[MemOpIdx++] = MMO;
1038+
}
1039+
1040+
// If any memory operand is updated, set memory references of
1041+
// this instruction.
1042+
if (ReplaceMemOps)
1043+
I.setMemRefs(std::make_pair(NewMemOps, I.getNumMemOperands()));
10001044
}
10011045

10021046
// Update the location of C++ catch objects for the MSVC personality routine.

0 commit comments

Comments
 (0)