[DebugInfo] Normalize common kinds of DWARF sub-expressions.

Normalize common kinds of DWARF sub-expressions to make debug info
encoding a bit more compact:

  DW_OP_constu [X < 32] -> DW_OP_litX
  DW_OP_constu [all ones] -> DW_OP_lit0, DW_OP_not (64-bit only)

Differential revision: https://reviews.llvm.org/D51640

llvm-svn: 341457
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
index d8d1a5e..af51d27 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
@@ -24,6 +24,20 @@
 
 using namespace llvm;
 
+void DwarfExpression::emitConstu(uint64_t Value) {
+  if (Value < 32)
+    emitOp(dwarf::DW_OP_lit0 + Value);
+  else if (Value == std::numeric_limits<uint64_t>::max()) {
+    // Only do this for 64-bit values as the DWARF expression stack uses
+    // target-address-size values.
+    emitOp(dwarf::DW_OP_lit0);
+    emitOp(dwarf::DW_OP_not);
+  } else {
+    emitOp(dwarf::DW_OP_constu);
+    emitUnsigned(Value);
+  }
+}
+
 void DwarfExpression::addReg(int DwarfReg, const char *Comment) {
  assert(DwarfReg >= 0 && "invalid negative dwarf register number");
  assert((LocationKind == Unknown || LocationKind == Register) &&
@@ -72,14 +86,12 @@
 }
 
 void DwarfExpression::addShr(unsigned ShiftBy) {
-  emitOp(dwarf::DW_OP_constu);
-  emitUnsigned(ShiftBy);
+  emitConstu(ShiftBy);
   emitOp(dwarf::DW_OP_shr);
 }
 
 void DwarfExpression::addAnd(unsigned Mask) {
-  emitOp(dwarf::DW_OP_constu);
-  emitUnsigned(Mask);
+  emitConstu(Mask);
   emitOp(dwarf::DW_OP_and);
 }
 
@@ -181,8 +193,7 @@
 void DwarfExpression::addUnsignedConstant(uint64_t Value) {
   assert(LocationKind == Implicit || LocationKind == Unknown);
   LocationKind = Implicit;
-  emitOp(dwarf::DW_OP_constu);
-  emitUnsigned(Value);
+  emitConstu(Value);
 }
 
 void DwarfExpression::addUnsignedConstant(const APInt &Value) {
@@ -373,8 +384,7 @@
       break;
     case dwarf::DW_OP_constu:
       assert(LocationKind != Register);
-      emitOp(dwarf::DW_OP_constu);
-      emitUnsigned(Op->getArg(0));
+      emitConstu(Op->getArg(0));
       break;
     case dwarf::DW_OP_stack_value:
       LocationKind = Implicit;
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
index 0637d95..d47c4d1 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
@@ -138,6 +138,9 @@
   /// Emit a raw unsigned value.
   virtual void emitUnsigned(uint64_t Value) = 0;
 
+  /// Emit a normalized unsigned constant.
+  void emitConstu(uint64_t Value);
+
   /// Return whether the given machine register is the frame register in the
   /// current function.
   virtual bool isFrameRegister(const TargetRegisterInfo &TRI, unsigned MachineReg) = 0;