paulkirth updated this revision to Diff 466919.
paulkirth added a comment.

Add SlotID to output

Improve some initialization

Still need to do significant code cleanup and testing


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D135488/new/

https://reviews.llvm.org/D135488

Files:
  clang/test/Frontend/frame-diags.c
  llvm/include/llvm/CodeGen/MachineFrameInfo.h
  llvm/lib/CodeGen/MachineFrameInfo.cpp
  llvm/lib/CodeGen/PrologEpilogInserter.cpp

Index: llvm/lib/CodeGen/PrologEpilogInserter.cpp
===================================================================
--- llvm/lib/CodeGen/PrologEpilogInserter.cpp
+++ llvm/lib/CodeGen/PrologEpilogInserter.cpp
@@ -289,6 +289,7 @@
   if (StackSize > Threshold) {
     DiagnosticInfoStackSize DiagStackSize(F, StackSize, Threshold, DS_Warning);
     F.getContext().diagnose(DiagStackSize);
+    MFI.pretty_print(MF, llvm::errs());
   }
   ORE->emit([&]() {
     return MachineOptimizationRemarkAnalysis(DEBUG_TYPE, "StackSize",
Index: llvm/lib/CodeGen/MachineFrameInfo.cpp
===================================================================
--- llvm/lib/CodeGen/MachineFrameInfo.cpp
+++ llvm/lib/CodeGen/MachineFrameInfo.cpp
@@ -20,9 +20,12 @@
 #include "llvm/CodeGen/TargetRegisterInfo.h"
 #include "llvm/CodeGen/TargetSubtargetInfo.h"
 #include "llvm/Config/llvm-config.h"
+#include "llvm/IR/DebugInfoMetadata.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
 #include <cassert>
+#include <iomanip>
+#include <sstream>
 
 #define DEBUG_TYPE "codegen"
 
@@ -249,6 +252,131 @@
   }
 }
 
+void MachineFrameInfo::pretty_print(const MachineFunction &MF,
+                                    raw_ostream &OS) const {
+  struct Data {
+    int Slot;
+    int Size;
+    int Align;
+    int Offset;
+    bool IsSpillSlot;
+    bool Fixed;
+  };
+  if (Objects.empty())
+    return;
+
+  const TargetFrameLowering *FI = MF.getSubtarget().getFrameLowering();
+  int ValOffset = (FI ? FI->getOffsetOfLocalArea() : 0);
+
+  std::vector<Data> SlotInfo;
+  SlotInfo.reserve(Objects.size());
+  // initialize slot info
+  for (unsigned i = 0, e =Objects.size(); i != e; ++i) {
+    Data D;
+    const StackObject &SO = Objects[i];
+    if (SO.Size == ~0ULL) {
+      continue;
+    }
+
+    D.Slot = (int)(i-NumFixedObjects);
+    // If Size == 0, then its a variable size object...
+    D.Size = SO.Size;
+    D.Align = SO.Alignment.value();
+    int64_t Off = SO.SPOffset - ValOffset;
+    D.Fixed = (i < NumFixedObjects);
+    D.Offset = Off;
+    SlotInfo.push_back(D);
+  }
+
+  // sort the ordering, to match the actual layout
+  std::sort(SlotInfo.begin(), SlotInfo.end(),
+            [](Data &A, Data &B) { return A.Offset > B.Offset; });
+
+  size_t MaxLine = 75;
+  auto PrintDashed = [&OS, MaxLine]() {
+    OS << "+";
+    for (size_t I = 0; I < MaxLine + 2; ++I) {
+      OS << "-";
+    }
+    OS << "+\n";
+  };
+
+  auto GetFieldInt = [](int Width, int I) {
+    std::stringstream SS;
+    SS << std::setw(Width) << I;
+    return SS.str();
+  };
+  auto GetFieldBool = [](int Width, bool I) {
+    std::stringstream SS;
+    SS << std::setw(Width) << (I ? "T" : "F");
+    return SS.str();
+  };
+  auto GetFieldString = [](int Width, std::string S) {
+    std::stringstream SS;
+    SS << std::setw(Width) << S;
+    return SS.str();
+  };
+  auto GetFieldOffset = [](int I) {
+    std::stringstream SS;
+    SS << "[SP";
+    const auto *Op = (I < 0) ? "" : "+";
+    SS << Op << I << "]";
+    return SS.str();
+  };
+
+  auto PrintRow = [&OS, MaxLine](std::string S) {
+    std::stringstream SS;
+    SS << std::setw(MaxLine) << S;
+    OS << "| " << SS.str() << " |\n";
+  };
+
+  const unsigned Columns = 7;
+  const int Width = MaxLine/Columns -2;
+
+  auto GetBody = [Width, &GetFieldInt, &GetFieldBool,
+                  &GetFieldOffset](int Idx, Data &D) {
+    std::stringstream SS;
+    SS << GetFieldInt(Width, Idx) << " | ";
+    SS << GetFieldInt(Width, D.Slot) << " | ";
+    SS << GetFieldInt(Width, D.Size) << " | ";
+    SS << GetFieldInt(Width, D.Align) << " | ";
+    SS << GetFieldBool(Width, D.Fixed) << " | ";
+    SS << GetFieldBool(Width, D.IsSpillSlot) << " | ";
+    SS << std::setw(Width) << GetFieldOffset(D.Offset);
+    return SS.str();
+  };
+
+  auto GetHeader = [Width, &GetFieldString]() {
+    std::stringstream SS;
+    SS << GetFieldString(Width, "Slot") << " | ";
+    SS << GetFieldString(Width, "SlotID") << " | ";
+    SS << GetFieldString(Width, "Size") << " | ";
+    SS << GetFieldString(Width, "Align") << " | ";
+    SS << GetFieldString(Width, "Fixed") << " | ";
+    SS << GetFieldString(Width, "Spill") << " | ";
+    SS << GetFieldString(Width, "Offset");
+    return SS.str();
+  };
+
+  PrintDashed();
+  PrintRow(MF.getName().str());
+  PrintDashed();
+  PrintRow(GetHeader());
+
+  int Idx = 0;
+  for (auto L : SlotInfo) {
+    std::stringstream SS;
+    auto Body = GetBody(Idx++, L);
+    PrintDashed();
+    PrintRow(Body);
+  }
+  PrintDashed();
+  for (auto &DI : MF.getVariableDbgInfo()) {
+    OS << "Variable: " << DI.Var->getName()  << " (line " <<DI.Var->getLine()<< " of "
+     <<DI.Var->getFilename()<<") in SlotID: " << DI.Slot << "\n";
+  }
+}
+
 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
 LLVM_DUMP_METHOD void MachineFrameInfo::dump(const MachineFunction &MF) const {
   print(MF, dbgs());
Index: llvm/include/llvm/CodeGen/MachineFrameInfo.h
===================================================================
--- llvm/include/llvm/CodeGen/MachineFrameInfo.h
+++ llvm/include/llvm/CodeGen/MachineFrameInfo.h
@@ -814,6 +814,7 @@
   /// Used by the MachineFunction printer to print information about
   /// stack objects. Implemented in MachineFunction.cpp.
   void print(const MachineFunction &MF, raw_ostream &OS) const;
+  void pretty_print(const MachineFunction &MF, raw_ostream &OS) const;
 
   /// dump - Print the function to stderr.
   void dump(const MachineFunction &MF) const;
Index: clang/test/Frontend/frame-diags.c
===================================================================
--- /dev/null
+++ clang/test/Frontend/frame-diags.c
@@ -0,0 +1,40 @@
+// TODO: This is not really a functional test yet, and needs to be rewritten. 
+// currently its just a copy of backend-diagnostics.c, and all of the run/test 
+// logic needs to be updated.
+//
+//
+// REQUIRES: x86-registered-target
+// Play around with backend reporting:
+// _REGULAR_: Regular behavior, no warning switch enabled.
+// _PROMOTE_: Promote warning to error.
+// _IGNORE_: Drop backend warning.
+//
+// RUN: not %clang_cc1 %s -fwarn-stack-size=0 -no-integrated-as -S -o - -triple=i386-apple-darwin 2> %t.err
+// RUN: FileCheck < %t.err %s --check-prefix=REGULAR --check-prefix=ASM
+// RUN: not %clang_cc1 %s -fwarn-stack-size=0 -no-integrated-as -S -o - -triple=i386-apple-darwin -Werror=frame-larger-than 2> %t.err
+// RUN: FileCheck < %t.err %s --check-prefix=PROMOTE --check-prefix=ASM
+// RUN: not %clang_cc1 %s -fwarn-stack-size=0 -no-integrated-as -S -o - -triple=i386-apple-darwin -Wno-frame-larger-than 2> %t.err
+// RUN: FileCheck < %t.err %s --check-prefix=IGNORE --check-prefix=ASM
+//
+// RUN: %clang_cc1 %s -S -o - -triple=i386-apple-darwin -verify -no-integrated-as
+
+extern void doIt(char *);
+extern void compareIt(char *, char *);
+extern int getNum(long);
+
+// REGULAR: warning: stack frame size ([[#]]) exceeds limit ([[#]]) in 'stackSizeWarning'
+// PROMOTE: error: stack frame size ([[#]]) exceeds limit ([[#]]) in 'stackSizeWarning'
+// IGNORE-NOT: stack frame size ([[#]]) exceeds limit ([[#]]) in 'stackSizeWarning'
+void stackSizeWarning(void) {
+  {
+    char buffer[80];
+    doIt(buffer);
+  }
+  char buffer2[80];
+  int a = 0;
+  long b = 1;
+  doIt(buffer2);
+  // compareIt(buffer, buffer2);
+  getNum(a);
+  getNum(b);
+}
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to