Skip to content

[KeyInstr][Clang] Assignment atom group #134637

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: users/OCHyams/ki-clang-init-static
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions clang/lib/CodeGen/CGExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5814,6 +5814,15 @@ LValue CodeGenFunction::EmitBinaryOperatorLValue(const BinaryOperator *E) {

assert(E->getOpcode() == BO_Assign && "unexpected binary l-value");

// This covers both LHS and RHS expressions, though nested RHS
// expressions may get subsequently separately grouped.
// FIXME(OCH): Not clear yet if we've got fine enough control
// to pick and choose when we need to. Currently looks ok:
// a = b = c -> Two atoms.
// x = new(1) -> One atom (for both addr store and value store).
// Complex and agg assignment -> One atom.
ApplyAtomGroup Grp(getDebugInfo());

// Note that in all of these cases, __block variables need the RHS
// evaluated first just in case the variable gets moved by the RHS.

Expand Down
4 changes: 4 additions & 0 deletions clang/lib/CodeGen/CGExprScalar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -897,6 +897,7 @@ class ScalarExprEmitter
return result; \
} \
Value *VisitBin##OP##Assign(const CompoundAssignOperator *E) { \
ApplyAtomGroup Grp(CGF.getDebugInfo()); \
return EmitCompoundAssign(E, &ScalarExprEmitter::Emit##OP); \
}
HANDLEBINOP(Mul)
Expand Down Expand Up @@ -2940,6 +2941,7 @@ class OMPLastprivateConditionalUpdateRAII {
llvm::Value *
ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
bool isInc, bool isPre) {
ApplyAtomGroup Grp(CGF.getDebugInfo());
OMPLastprivateConditionalUpdateRAII OMPRegion(CGF, E);
QualType type = E->getSubExpr()->getType();
llvm::PHINode *atomicPHI = nullptr;
Expand Down Expand Up @@ -4973,6 +4975,7 @@ llvm::Value *CodeGenFunction::EmitWithOriginalRHSBitfieldAssignment(
}

Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) {
ApplyAtomGroup Grp(CGF.getDebugInfo());
bool Ignore = TestAndClearIgnoreResultAssign();

Value *RHS;
Expand Down Expand Up @@ -5740,6 +5743,7 @@ LValue CodeGenFunction::EmitObjCIsaExpr(const ObjCIsaExpr *E) {

LValue CodeGenFunction::EmitCompoundAssignmentLValue(
const CompoundAssignOperator *E) {
ApplyAtomGroup Grp(getDebugInfo());
ScalarExprEmitter Scalar(*this);
Value *Result = nullptr;
switch (E->getOpcode()) {
Expand Down
48 changes: 48 additions & 0 deletions clang/test/KeyInstructions/assign-scalar.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// RUN: %clang -gkey-instructions -x c++ %s -gmlt -gcolumn-info -S -emit-llvm -o - -Wno-unused-variable \
// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank

// RUN: %clang -gkey-instructions -x c %s -gmlt -gcolumn-info -S -emit-llvm -o - -Wno-unused-variable \
// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank

unsigned long long g;
void fun() {
// CHECK: store i64 0, ptr @g{{.*}}, !dbg [[G1R1:!.*]]
g = 0;

// Treat the two assignments as two atoms.
//
// FIXME: Because of the atomGroup implementation the load can only be
// associated with one of the two stores, despite being a good backup
// loction for both.
// CHECK-NEXT: %0 = load i64, ptr @g{{.*}}, !dbg [[G2R2:!.*]]
// CHECK-NEXT: store i64 %0, ptr @g{{.*}}, !dbg [[G3R1:!.*]]
// CHECK-NEXT: store i64 %0, ptr @g{{.*}}, !dbg [[G2R1:!.*]]
g = g = g;

// Compound assignment.
// CHECK: %1 = load i64, ptr @g
// CHECK: %add = add i64 %1, 50, !dbg [[G4R2:!.*]]
// CHECK: store i64 %add, ptr @g{{.*}}, !dbg [[G4R1:!.*]]
g += 50;

// Pre/Post Inc/Dec.
// CHECK: %2 = load i64, ptr @g
// CHECK: %inc = add i64 %2, 1, !dbg [[G5R2:!.*]]
// CHECK: store i64 %inc, ptr @g{{.*}}, !dbg [[G5R1:!.*]]
++g;
// CHECK: %3 = load i64, ptr @g
// CHECK: %dec = add i64 %3, -1, !dbg [[G6R2:!.*]]
// CHECK: store i64 %dec, ptr @g{{.*}}, !dbg [[G6R1:!.*]]
g--;
}

// CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
// CHECK: [[G2R2]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 2)
// CHECK: [[G3R1]] = !DILocation({{.*}}, atomGroup: 3, atomRank: 1)
// CHECK: [[G2R1]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1)
// CHECK: [[G4R2]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 2)
// CHECK: [[G4R1]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 1)
// CHECK: [[G5R2]] = !DILocation({{.*}}, atomGroup: 5, atomRank: 2)
// CHECK: [[G5R1]] = !DILocation({{.*}}, atomGroup: 5, atomRank: 1)
// CHECK: [[G6R2]] = !DILocation({{.*}}, atomGroup: 6, atomRank: 2)
// CHECK: [[G6R1]] = !DILocation({{.*}}, atomGroup: 6, atomRank: 1)
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@

// RUN: %clang -gkey-instructions %s -gmlt -gno-column-info -S -emit-llvm -o - -ftrivial-auto-var-init=pattern \
// RUN: %clang -gkey-instructions -x c++ %s -gmlt -gno-column-info -S -emit-llvm -o - -ftrivial-auto-var-init=pattern \
// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank

// RUN: %clang -gkey-instructions -x c %s -gmlt -gno-column-info -S -emit-llvm -o - -ftrivial-auto-var-init=pattern \
// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank

// The implicit-check-not is important; we don't want the GEPs created for the
// store locations to be included in the atom group.

int g;
void a() {
// CHECK: _Z1av()
// CHECK: call void @llvm.memcpy{{.*}}, !dbg [[G1R1:!.*]]
int A[] = { 1, 2, 3 };

Expand Down
Loading