[llvm] 4753a69 - [Remarks] Provide more information about auto-init stores

Francis Visoiu Mistrih via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 25 15:14:41 PST 2021


Author: Francis Visoiu Mistrih
Date: 2021-02-25T15:14:09-08:00
New Revision: 4753a69a316b7705fc1b1442ad88afac059d542f

URL: https://github.com/llvm/llvm-project/commit/4753a69a316b7705fc1b1442ad88afac059d542f
DIFF: https://github.com/llvm/llvm-project/commit/4753a69a316b7705fc1b1442ad88afac059d542f.diff

LOG: [Remarks] Provide more information about auto-init stores

This adds support for analyzing the instruction with the !annotation
"auto-init" in order to generate a more user-friendly remark.

For now, support the store size, and whether it's atomic/volatile.

Example:

```
auto-init.c:4:7: remark: Store inserted by -ftrivial-auto-var-init.Store size: 4 bytes. [-Rpass-missed=annotation-remarks]
  int var;
      ^
```

Differential Revision: https://reviews.llvm.org/D97412

Added: 
    llvm/include/llvm/Transforms/Utils/AutoInitRemark.h
    llvm/lib/Transforms/Utils/AutoInitRemark.cpp

Modified: 
    llvm/lib/Transforms/Scalar/AnnotationRemarks.cpp
    llvm/lib/Transforms/Utils/CMakeLists.txt
    llvm/test/Transforms/Util/trivial-auto-var-init-store.ll

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Transforms/Utils/AutoInitRemark.h b/llvm/include/llvm/Transforms/Utils/AutoInitRemark.h
new file mode 100644
index 000000000000..b02db96ec41d
--- /dev/null
+++ b/llvm/include/llvm/Transforms/Utils/AutoInitRemark.h
@@ -0,0 +1,44 @@
+//===- AutoInitRemark.h - Auto-init remark analysis -*- C++ -------------*-===//
+//
+//                      The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Provide more information about instructions with a "auto-init"
+// !annotation metadata.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_AUTOINITREMARK_H
+#define LLVM_TRANSFORMS_UTILS_AUTOINITREMARK_H
+
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+
+class StoreInst;
+class Instruction;
+class OptimizationRemarkEmitter;
+class DataLayout;
+
+// FIXME: Once we get to more remarks like this one, we need to re-evaluate how
+// much of this logic should actually go into the remark emitter.
+struct AutoInitRemark {
+  OptimizationRemarkEmitter &ORE;
+  StringRef RemarkPass;
+  const DataLayout &DL;
+
+  AutoInitRemark(OptimizationRemarkEmitter &ORE, StringRef RemarkPass,
+                 const DataLayout &DL)
+      : ORE(ORE), RemarkPass(RemarkPass), DL(DL) {}
+
+  void inspectStore(StoreInst &SI);
+  void inspectUnknown(Instruction &I);
+};
+
+} // namespace llvm
+
+#endif

diff  --git a/llvm/lib/Transforms/Scalar/AnnotationRemarks.cpp b/llvm/lib/Transforms/Scalar/AnnotationRemarks.cpp
index b7aaa8e1df7e..58c287156612 100644
--- a/llvm/lib/Transforms/Scalar/AnnotationRemarks.cpp
+++ b/llvm/lib/Transforms/Scalar/AnnotationRemarks.cpp
@@ -16,10 +16,12 @@
 #include "llvm/Analysis/TargetLibraryInfo.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/InstIterator.h"
+#include "llvm/IR/Instructions.h"
 #include "llvm/InitializePasses.h"
 #include "llvm/Pass.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Utils/AutoInitRemark.h"
 
 using namespace llvm;
 using namespace llvm::ore;
@@ -38,9 +40,20 @@ static void tryEmitAutoInitRemark(ArrayRef<Instruction *> Instructions,
       if (cast<MDString>(Op.get())->getString() != "auto-init")
         continue;
 
-      ORE.emit(
-          OptimizationRemarkMissed(REMARK_PASS, "AutoInitUnknownInstruction", I)
-          << "Initialization inserted by -ftrivial-auto-var-init.");
+      Function &F = *I->getParent()->getParent();
+      const DataLayout &DL = F.getParent()->getDataLayout();
+      AutoInitRemark Remark(ORE, REMARK_PASS, DL);
+      // For some of them, we can provide more information:
+
+      // For stores:
+      // * size
+      // * volatile / atomic
+      if (auto *SI = dyn_cast<StoreInst>(I)) {
+        Remark.inspectStore(*SI);
+        continue;
+      }
+
+      Remark.inspectUnknown(*I);
     }
   }
 }

diff  --git a/llvm/lib/Transforms/Utils/AutoInitRemark.cpp b/llvm/lib/Transforms/Utils/AutoInitRemark.cpp
new file mode 100644
index 000000000000..6cfeda880142
--- /dev/null
+++ b/llvm/lib/Transforms/Utils/AutoInitRemark.cpp
@@ -0,0 +1,49 @@
+//===-- AutoInitRemark.cpp - Auto-init remark analysis---------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Implementation of the analysis for the "auto-init" remark.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/Utils/AutoInitRemark.h"
+#include "llvm/Analysis/OptimizationRemarkEmitter.h"
+#include "llvm/IR/Instructions.h"
+
+using namespace llvm;
+using namespace llvm::ore;
+
+void AutoInitRemark::inspectStore(StoreInst &SI) {
+  bool Volatile = SI.isVolatile();
+  bool Atomic = SI.isAtomic();
+  int64_t Size = DL.getTypeStoreSize(SI.getOperand(0)->getType());
+
+  OptimizationRemarkMissed R(RemarkPass.data(), "AutoInitStore", &SI);
+  R << "Store inserted by -ftrivial-auto-var-init.\nStore size: "
+    << NV("StoreSize", Size) << " bytes.";
+  if (Volatile)
+    R << " Volatile: " << NV("StoreVolatile", true) << ".";
+  if (Atomic)
+    R << " Atomic: " << NV("StoreAtomic", true) << ".";
+  // Emit StoreVolatile: false and StoreAtomic: false under ExtraArgs. This
+  // won't show them in the remark message but will end up in the serialized
+  // remarks.
+  if (!Volatile || !Atomic)
+    R << setExtraArgs();
+  if (!Volatile)
+    R << " Volatile: " << NV("StoreVolatile", false) << ".";
+  if (!Atomic)
+    R << " Atomic: " << NV("StoreAtomic", false) << ".";
+
+  ORE.emit(R);
+}
+
+void AutoInitRemark::inspectUnknown(Instruction &I) {
+  ORE.emit(OptimizationRemarkMissed(RemarkPass.data(),
+                                    "AutoInitUnknownInstruction", &I)
+           << "Initialization inserted by -ftrivial-auto-var-init.");
+}

diff  --git a/llvm/lib/Transforms/Utils/CMakeLists.txt b/llvm/lib/Transforms/Utils/CMakeLists.txt
index dc6d21f9e8f0..7eb2d51a0593 100644
--- a/llvm/lib/Transforms/Utils/CMakeLists.txt
+++ b/llvm/lib/Transforms/Utils/CMakeLists.txt
@@ -3,6 +3,7 @@ add_llvm_component_library(LLVMTransformUtils
   AMDGPUEmitPrintf.cpp
   ASanStackFrameLayout.cpp
   AssumeBundleBuilder.cpp
+  AutoInitRemark.cpp
   BasicBlockUtils.cpp
   BreakCriticalEdges.cpp
   BuildLibCalls.cpp

diff  --git a/llvm/test/Transforms/Util/trivial-auto-var-init-store.ll b/llvm/test/Transforms/Util/trivial-auto-var-init-store.ll
index c199daf1331d..adff4dec60e3 100644
--- a/llvm/test/Transforms/Util/trivial-auto-var-init-store.ll
+++ b/llvm/test/Transforms/Util/trivial-auto-var-init-store.ll
@@ -3,14 +3,23 @@
 
 ; Emit a remark that reports a store.
 define void @store(i32* %dst) {
-; CHECK: Initialization inserted by -ftrivial-auto-var-init.
+; CHECK:      Store inserted by -ftrivial-auto-var-init.
+; CHECK-NEXT: Store size: 4 bytes.
 ; YAML-LABEL: --- !Missed
 ; YAML-NEXT: Pass:            annotation-remarks
-; YAML-NEXT: Name:            AutoInitUnknownInstruction
+; YAML-NEXT: Name:            AutoInitStore
 ; YAML-NEXT: DebugLoc:
 ; YAML-NEXT: Function:        store
 ; YAML-NEXT: Args:
-; YAML-NEXT:   - String:          Initialization inserted by -ftrivial-auto-var-init.
+; YAML-NEXT:   - String:          "Store inserted by -ftrivial-auto-var-init.\nStore size: "
+; YAML-NEXT:   - StoreSize:       '4'
+; YAML-NEXT:   - String:          ' bytes.'
+; YAML-NEXT:   - String:          ' Volatile: '
+; YAML-NEXT:   - StoreVolatile:       'false'
+; YAML-NEXT:   - String:          .
+; YAML-NEXT:   - String:          ' Atomic: '
+; YAML-NEXT:   - StoreAtomic:       'false'
+; YAML-NEXT:   - String:          .
 ; YAML-NEXT: ...
   store i32 0, i32* %dst, !annotation !0, !dbg !DILocation(scope: !4)
   ret void
@@ -18,14 +27,23 @@ define void @store(i32* %dst) {
 
 ; Emit a remark that reports a volatile store.
 define void @volatile_store(i32* %dst) {
-; CHECK-NEXT: Initialization inserted by -ftrivial-auto-var-init.
+; CHECK-NEXT: Store inserted by -ftrivial-auto-var-init.
+; CHECK-NEXT: Store size: 4 bytes. Volatile: true.
 ; YAML-LABEL: --- !Missed
 ; YAML-NEXT: Pass:            annotation-remarks
-; YAML-NEXT: Name:            AutoInitUnknownInstruction
+; YAML-NEXT: Name:            AutoInitStore
 ; YAML-NEXT: DebugLoc:
 ; YAML-NEXT: Function:        volatile_store
 ; YAML-NEXT: Args:
-; YAML-NEXT:   - String:          Initialization inserted by -ftrivial-auto-var-init.
+; YAML-NEXT:   - String:          "Store inserted by -ftrivial-auto-var-init.\nStore size: "
+; YAML-NEXT:   - StoreSize:       '4'
+; YAML-NEXT:   - String:          ' bytes.'
+; YAML-NEXT:   - String:          ' Volatile: '
+; YAML-NEXT:   - StoreVolatile:       'true'
+; YAML-NEXT:   - String:          .
+; YAML-NEXT:   - String:          ' Atomic: '
+; YAML-NEXT:   - StoreAtomic:       'false'
+; YAML-NEXT:   - String:          .
 ; YAML-NEXT: ...
   store volatile i32 0, i32* %dst, !annotation !0, !dbg !DILocation(scope: !4)
   ret void
@@ -33,14 +51,23 @@ define void @volatile_store(i32* %dst) {
 
 ; Emit a remark that reports an atomic store.
 define void @atomic_store(i32* %dst) {
-; CHECK-NEXT: Initialization inserted by -ftrivial-auto-var-init.
+; CHECK-NEXT: Store inserted by -ftrivial-auto-var-init.
+; CHECK-NEXT: Store size: 4 bytes. Atomic: true.
 ; YAML-LABEL: --- !Missed
 ; YAML-NEXT: Pass:            annotation-remarks
-; YAML-NEXT: Name:            AutoInitUnknownInstruction
+; YAML-NEXT: Name:            AutoInitStore
 ; YAML-NEXT: DebugLoc:
 ; YAML-NEXT: Function:        atomic_store
 ; YAML-NEXT: Args:
-; YAML-NEXT:   - String:          Initialization inserted by -ftrivial-auto-var-init.
+; YAML-NEXT:   - String:          "Store inserted by -ftrivial-auto-var-init.\nStore size: "
+; YAML-NEXT:   - StoreSize:       '4'
+; YAML-NEXT:   - String:          ' bytes.'
+; YAML-NEXT:   - String:          ' Atomic: '
+; YAML-NEXT:   - StoreAtomic:       'true'
+; YAML-NEXT:   - String:          .
+; YAML-NEXT:   - String:          ' Volatile: '
+; YAML-NEXT:   - StoreVolatile:       'false'
+; YAML-NEXT:   - String:          .
 ; YAML-NEXT: ...
   store atomic i32 0, i32* %dst unordered, align 4, !annotation !0, !dbg !DILocation(scope: !4)
   ret void
@@ -48,14 +75,23 @@ define void @atomic_store(i32* %dst) {
 
 ; Emit a remark that reports a store to an alloca.
 define void @store_alloca() {
-; CHECK-NEXT: Initialization inserted by -ftrivial-auto-var-init.
+; CHECK-NEXT: Store inserted by -ftrivial-auto-var-init.
+; CHECK-NEXT: Store size: 4 bytes.
 ; YAML-LABEL: --- !Missed
 ; YAML-NEXT: Pass:            annotation-remarks
-; YAML-NEXT: Name:            AutoInitUnknownInstruction
+; YAML-NEXT: Name:            AutoInitStore
 ; YAML-NEXT: DebugLoc:
 ; YAML-NEXT: Function:        store_alloca
 ; YAML-NEXT: Args:
-; YAML-NEXT:   - String:          Initialization inserted by -ftrivial-auto-var-init.
+; YAML-NEXT:   - String:          "Store inserted by -ftrivial-auto-var-init.\nStore size: "
+; YAML-NEXT:   - StoreSize:       '4'
+; YAML-NEXT:   - String:          ' bytes.'
+; YAML-NEXT:   - String:          ' Volatile: '
+; YAML-NEXT:   - StoreVolatile:       'false'
+; YAML-NEXT:   - String:          .
+; YAML-NEXT:   - String:          ' Atomic: '
+; YAML-NEXT:   - StoreAtomic:       'false'
+; YAML-NEXT:   - String:          .
 ; YAML-NEXT: ...
   %dst = alloca i32
   store i32 0, i32* %dst, !annotation !0, !dbg !DILocation(scope: !4)
@@ -64,7 +100,8 @@ define void @store_alloca() {
 
 ; Emit a remark that reports a store to an alloca through a GEP.
 define void @store_alloca_gep() {
-; CHECK-NEXT: Initialization inserted by -ftrivial-auto-var-init.
+; CHECK-NEXT: Store inserted by -ftrivial-auto-var-init.
+; CHECK-NEXT: Store size: 4 bytes.
   %dst = alloca i32
   %gep = getelementptr i32, i32* %dst, i32 0
   store i32 0, i32* %gep, !annotation !0, !dbg !DILocation(scope: !4)
@@ -73,7 +110,8 @@ define void @store_alloca_gep() {
 
 ; Emit a remark that reports a store to an alloca through a GEP in an array.
 define void @store_alloca_gep_array() {
-; CHECK-NEXT: Initialization inserted by -ftrivial-auto-var-init.
+; CHECK-NEXT: Store inserted by -ftrivial-auto-var-init.
+; CHECK-NEXT: Store size: 4 bytes.
   %dst = alloca [2 x i32]
   %gep = getelementptr [2 x i32], [2 x i32]* %dst, i64 0, i64 0
   store i32 0, i32* %gep, !annotation !0, !dbg !DILocation(scope: !4)
@@ -82,7 +120,8 @@ define void @store_alloca_gep_array() {
 
 ; Emit a remark that reports a store to an alloca through a bitcast.
 define void @store_alloca_bitcast() {
-; CHECK-NEXT: Initialization inserted by -ftrivial-auto-var-init.
+; CHECK-NEXT: Store inserted by -ftrivial-auto-var-init.
+; CHECK-NEXT: Store size: 4 bytes.
   %dst = alloca [2 x i16]
   %bc = bitcast [2 x i16]* %dst to i32*
   store i32 0, i32* %bc, !annotation !0, !dbg !DILocation(scope: !4)
@@ -92,7 +131,8 @@ define void @store_alloca_bitcast() {
 ; Emit a remark that reports a store to an alloca that has a DILocalVariable
 ; attached.
 define void @store_alloca_di() {
-; CHECK-NEXT: Initialization inserted by -ftrivial-auto-var-init.
+; CHECK-NEXT: Store inserted by -ftrivial-auto-var-init.
+; CHECK-NEXT: Store size: 4 bytes.
   %dst = alloca i32
   store i32 0, i32* %dst, !annotation !0, !dbg !DILocation(scope: !4)
   call void @llvm.dbg.declare(metadata i32* %dst, metadata !6, metadata !DIExpression()), !dbg !DILocation(scope: !4)
@@ -102,7 +142,8 @@ define void @store_alloca_di() {
 ; Emit a remark that reports a store to an alloca that has more than one
 ; DILocalVariable attached.
 define void @store_alloca_di_multiple() {
-; CHECK-NEXT: Initialization inserted by -ftrivial-auto-var-init.
+; CHECK-NEXT: Store inserted by -ftrivial-auto-var-init.
+; CHECK-NEXT: Store size: 4 bytes.
   %dst = alloca i32
   store i32 0, i32* %dst, !annotation !0, !dbg !DILocation(scope: !4)
   call void @llvm.dbg.declare(metadata i32* %dst, metadata !6, metadata !DIExpression()), !dbg !DILocation(scope: !4)
@@ -113,7 +154,8 @@ define void @store_alloca_di_multiple() {
 ; Emit a remark that reports a store to a PHI node that can be two 
diff erent
 ; allocas.
 define void @store_alloca_phi() {
-; CHECK-NEXT: Initialization inserted by -ftrivial-auto-var-init.
+; CHECK-NEXT: Store inserted by -ftrivial-auto-var-init.
+; CHECK-NEXT: Store size: 4 bytes.
 entry:
   %dst = alloca i32
   %dst2 = alloca i32
@@ -132,7 +174,8 @@ l2:
 ; Emit a remark that reports a store to a PHI node that can be two 
diff erent
 ; allocas, where one of it has multiple DILocalVariable.
 define void @store_alloca_phi_di_multiple() {
-; CHECK-NEXT: Initialization inserted by -ftrivial-auto-var-init.
+; CHECK-NEXT: Store inserted by -ftrivial-auto-var-init.
+; CHECK-NEXT: Store size: 4 bytes.
 entry:
   %dst = alloca i32
   %dst2 = alloca i32


        


More information about the llvm-commits mailing list