<div dir="ltr">We end up leaking TheNoneToken. I took a look, but fixing it wasn't straightforward.</div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Nov 11, 2015 at 1:57 PM, David Majnemer via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: majnemer<br>
Date: Wed Nov 11 15:57:16 2015<br>
New Revision: 252811<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=252811&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=252811&view=rev</a><br>
Log:<br>
[IR] Add support for empty tokens<br>
<br>
When working with tokens, it is often the case that one has instructions<br>
which consume a token and produce a new token.  Currently, we have no<br>
mechanism to represent an initial token state.<br>
<br>
Instead, we can create a notional "empty token" by inventing a new<br>
constant which captures the semantics we would like.  This new constant<br>
is called ConstantTokenNone and is written textually as "token none".<br>
<br>
Differential Revision: <a href="http://reviews.llvm.org/D14581" rel="noreferrer" target="_blank">http://reviews.llvm.org/D14581</a><br>
<br>
Modified:<br>
    llvm/trunk/docs/LangRef.rst<br>
    llvm/trunk/include/llvm-c/Core.h<br>
    llvm/trunk/include/llvm/IR/Constants.h<br>
    llvm/trunk/include/llvm/IR/Value.def<br>
    llvm/trunk/lib/AsmParser/LLLexer.cpp<br>
    llvm/trunk/lib/AsmParser/LLParser.cpp<br>
    llvm/trunk/lib/AsmParser/LLParser.h<br>
    llvm/trunk/lib/AsmParser/LLToken.h<br>
    llvm/trunk/lib/IR/AsmWriter.cpp<br>
    llvm/trunk/lib/IR/Constants.cpp<br>
    llvm/trunk/lib/IR/LLVMContextImpl.cpp<br>
    llvm/trunk/lib/IR/LLVMContextImpl.h<br>
    llvm/trunk/lib/Transforms/IPO/MergeFunctions.cpp<br>
    llvm/trunk/test/Assembler/token.ll<br>
<br>
Modified: llvm/trunk/docs/LangRef.rst<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=252811&r1=252810&r2=252811&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=252811&r1=252810&r2=252811&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/docs/LangRef.rst (original)<br>
+++ llvm/trunk/docs/LangRef.rst Wed Nov 11 15:57:16 2015<br>
@@ -2434,6 +2434,9 @@ Simple Constants<br>
 **Null pointer constants**<br>
     The identifier '``null``' is recognized as a null pointer constant<br>
     and must be of :ref:`pointer type <t_pointer>`.<br>
+**Token constants**<br>
+    The identifier '``none``' is recognized as an empty token constant<br>
+    and must be of :ref:`token type <t_token>`.<br>
<br>
 The one non-intuitive notation for constants is the hexadecimal form of<br>
 floating point constants. For example, the form<br>
<br>
Modified: llvm/trunk/include/llvm-c/Core.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm-c/Core.h?rev=252811&r1=252810&r2=252811&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm-c/Core.h?rev=252811&r1=252810&r2=252811&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm-c/Core.h (original)<br>
+++ llvm/trunk/include/llvm-c/Core.h Wed Nov 11 15:57:16 2015<br>
@@ -1185,6 +1185,7 @@ LLVMTypeRef LLVMX86MMXType(void);<br>
       macro(ConstantInt)                    \<br>
       macro(ConstantPointerNull)            \<br>
       macro(ConstantStruct)                 \<br>
+      macro(ConstantTokenNone)              \<br>
       macro(ConstantVector)                 \<br>
       macro(GlobalValue)                    \<br>
         macro(GlobalAlias)                  \<br>
<br>
Modified: llvm/trunk/include/llvm/IR/Constants.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Constants.h?rev=252811&r1=252810&r2=252811&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Constants.h?rev=252811&r1=252810&r2=252811&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/IR/Constants.h (original)<br>
+++ llvm/trunk/include/llvm/IR/Constants.h Wed Nov 11 15:57:16 2015<br>
@@ -795,7 +795,32 @@ public:<br>
   }<br>
 };<br>
<br>
+//===----------------------------------------------------------------------===//<br>
+/// ConstantTokenNone - a constant token which is empty<br>
+///<br>
+class ConstantTokenNone : public Constant {<br>
+  void *operator new(size_t, unsigned) = delete;<br>
+  ConstantTokenNone(const ConstantTokenNone &) = delete;<br>
+<br>
+  friend class Constant;<br>
+  void destroyConstantImpl();<br>
+  Value *handleOperandChangeImpl(Value *From, Value *To, Use *U);<br>
+<br>
+protected:<br>
+  explicit ConstantTokenNone(LLVMContext &Context)<br>
+      : Constant(Type::getTokenTy(Context), ConstantTokenNoneVal, nullptr, 0) {}<br>
+  // allocate space for exactly zero operands<br>
+  void *operator new(size_t s) { return User::operator new(s, 0); }<br>
<br>
+public:<br>
+  /// Return the ConstantTokenNone.<br>
+  static ConstantTokenNone *get(LLVMContext &Context);<br>
+<br>
+  /// @brief Methods to support type inquiry through isa, cast, and dyn_cast.<br>
+  static bool classof(const Value *V) {<br>
+    return V->getValueID() == ConstantTokenNoneVal;<br>
+  }<br>
+};<br>
<br>
 /// BlockAddress - The address of a basic block.<br>
 ///<br>
<br>
Modified: llvm/trunk/include/llvm/IR/Value.def<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Value.def?rev=252811&r1=252810&r2=252811&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Value.def?rev=252811&r1=252810&r2=252811&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/IR/Value.def (original)<br>
+++ llvm/trunk/include/llvm/IR/Value.def Wed Nov 11 15:57:16 2015<br>
@@ -70,6 +70,7 @@ HANDLE_CONSTANT(ConstantArray)<br>
 HANDLE_CONSTANT(ConstantStruct)<br>
 HANDLE_CONSTANT(ConstantVector)<br>
 HANDLE_CONSTANT(ConstantPointerNull)<br>
+HANDLE_CONSTANT(ConstantTokenNone)<br>
<br>
 HANDLE_METADATA_VALUE(MetadataAsValue)<br>
 HANDLE_INLINE_ASM_VALUE(InlineAsm)<br>
@@ -79,7 +80,7 @@ HANDLE_INSTRUCTION(Instruction)<br>
 // don't add new values here!<br>
<br>
 HANDLE_CONSTANT_MARKER(ConstantFirstVal, Function)<br>
-HANDLE_CONSTANT_MARKER(ConstantLastVal, ConstantPointerNull)<br>
+HANDLE_CONSTANT_MARKER(ConstantLastVal, ConstantTokenNone)<br>
<br>
 #undef HANDLE_GLOBAL_VALUE<br>
 #undef HANDLE_CONSTANT<br>
<br>
Modified: llvm/trunk/lib/AsmParser/LLLexer.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLLexer.cpp?rev=252811&r1=252810&r2=252811&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLLexer.cpp?rev=252811&r1=252810&r2=252811&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/AsmParser/LLLexer.cpp (original)<br>
+++ llvm/trunk/lib/AsmParser/LLLexer.cpp Wed Nov 11 15:57:16 2015<br>
@@ -523,6 +523,7 @@ lltok::Kind LLLexer::LexIdentifier() {<br>
   KEYWORD(zeroinitializer);<br>
   KEYWORD(undef);<br>
   KEYWORD(null);<br>
+  KEYWORD(none);<br>
   KEYWORD(to);<br>
   KEYWORD(caller);<br>
   KEYWORD(tail);<br>
<br>
Modified: llvm/trunk/lib/AsmParser/LLParser.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=252811&r1=252810&r2=252811&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=252811&r1=252810&r2=252811&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/AsmParser/LLParser.cpp (original)<br>
+++ llvm/trunk/lib/AsmParser/LLParser.cpp Wed Nov 11 15:57:16 2015<br>
@@ -2622,6 +2622,7 @@ bool LLParser::ParseValID(ValID &ID, Per<br>
   case lltok::kw_null: ID.Kind = ValID::t_Null; break;<br>
   case lltok::kw_undef: ID.Kind = ValID::t_Undef; break;<br>
   case lltok::kw_zeroinitializer: ID.Kind = ValID::t_Zero; break;<br>
+  case lltok::kw_none: ID.Kind = ValID::t_None; break;<br>
<br>
   case lltok::lbrace: {<br>
     // ValID ::= '{' ConstVector '}'<br>
@@ -4255,6 +4256,11 @@ bool LLParser::ConvertValIDToValue(Type<br>
       return Error(ID.Loc, "invalid type for null constant");<br>
     V = Constant::getNullValue(Ty);<br>
     return false;<br>
+  case ValID::t_None:<br>
+    if (!Ty->isTokenTy())<br>
+      return Error(ID.Loc, "invalid type for none constant");<br>
+    V = Constant::getNullValue(Ty);<br>
+    return false;<br>
   case ValID::t_Constant:<br>
     if (ID.ConstantVal->getType() != Ty)<br>
       return Error(ID.Loc, "constant expression type mismatch");<br>
<br>
Modified: llvm/trunk/lib/AsmParser/LLParser.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.h?rev=252811&r1=252810&r2=252811&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.h?rev=252811&r1=252810&r2=252811&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/AsmParser/LLParser.h (original)<br>
+++ llvm/trunk/lib/AsmParser/LLParser.h Wed Nov 11 15:57:16 2015<br>
@@ -46,15 +46,15 @@ namespace llvm {<br>
   /// or a symbolic (%var) reference.  This is just a discriminated union.<br>
   struct ValID {<br>
     enum {<br>
-      t_LocalID, t_GlobalID,      // ID in UIntVal.<br>
-      t_LocalName, t_GlobalName,  // Name in StrVal.<br>
-      t_APSInt, t_APFloat,        // Value in APSIntVal/APFloatVal.<br>
-      t_Null, t_Undef, t_Zero,    // No value.<br>
-      t_EmptyArray,               // No value:  []<br>
-      t_Constant,                 // Value in ConstantVal.<br>
-      t_InlineAsm,                // Value in FTy/StrVal/StrVal2/UIntVal.<br>
-      t_ConstantStruct,           // Value in ConstantStructElts.<br>
-      t_PackedConstantStruct      // Value in ConstantStructElts.<br>
+      t_LocalID, t_GlobalID,           // ID in UIntVal.<br>
+      t_LocalName, t_GlobalName,       // Name in StrVal.<br>
+      t_APSInt, t_APFloat,             // Value in APSIntVal/APFloatVal.<br>
+      t_Null, t_Undef, t_Zero, t_None, // No value.<br>
+      t_EmptyArray,                    // No value:  []<br>
+      t_Constant,                      // Value in ConstantVal.<br>
+      t_InlineAsm,                     // Value in FTy/StrVal/StrVal2/UIntVal.<br>
+      t_ConstantStruct,                // Value in ConstantStructElts.<br>
+      t_PackedConstantStruct           // Value in ConstantStructElts.<br>
     } Kind = t_LocalID;<br>
<br>
     LLLexer::LocTy Loc;<br>
<br>
Modified: llvm/trunk/lib/AsmParser/LLToken.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLToken.h?rev=252811&r1=252810&r2=252811&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLToken.h?rev=252811&r1=252810&r2=252811&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/AsmParser/LLToken.h (original)<br>
+++ llvm/trunk/lib/AsmParser/LLToken.h Wed Nov 11 15:57:16 2015<br>
@@ -49,7 +49,7 @@ namespace lltok {<br>
     kw_external, kw_thread_local,<br>
     kw_localdynamic, kw_initialexec, kw_localexec,<br>
     kw_zeroinitializer,<br>
-    kw_undef, kw_null,<br>
+    kw_undef, kw_null, kw_none,<br>
     kw_to,<br>
     kw_caller,<br>
     kw_tail,<br>
<br>
Modified: llvm/trunk/lib/IR/AsmWriter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/AsmWriter.cpp?rev=252811&r1=252810&r2=252811&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/AsmWriter.cpp?rev=252811&r1=252810&r2=252811&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/IR/AsmWriter.cpp (original)<br>
+++ llvm/trunk/lib/IR/AsmWriter.cpp Wed Nov 11 15:57:16 2015<br>
@@ -1328,6 +1328,11 @@ static void WriteConstantInternal(raw_os<br>
     return;<br>
   }<br>
<br>
+  if (isa<ConstantTokenNone>(CV)) {<br>
+    Out << "none";<br>
+    return;<br>
+  }<br>
+<br>
   if (isa<UndefValue>(CV)) {<br>
     Out << "undef";<br>
     return;<br>
<br>
Modified: llvm/trunk/lib/IR/Constants.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Constants.cpp?rev=252811&r1=252810&r2=252811&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Constants.cpp?rev=252811&r1=252810&r2=252811&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/IR/Constants.cpp (original)<br>
+++ llvm/trunk/lib/IR/Constants.cpp Wed Nov 11 15:57:16 2015<br>
@@ -81,8 +81,10 @@ bool Constant::isNullValue() const {<br>
   if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this))<br>
     return CFP->isZero() && !CFP->isNegative();<br>
<br>
-  // constant zero is zero for aggregates and cpnull is null for pointers.<br>
-  return isa<ConstantAggregateZero>(this) || isa<ConstantPointerNull>(this);<br>
+  // constant zero is zero for aggregates, cpnull is null for pointers, none for<br>
+  // tokens.<br>
+  return isa<ConstantAggregateZero>(this) || isa<ConstantPointerNull>(this) ||<br>
+         isa<ConstantTokenNone>(this);<br>
 }<br>
<br>
 bool Constant::isAllOnesValue() const {<br>
@@ -204,6 +206,8 @@ Constant *Constant::getNullValue(Type *T<br>
   case Type::ArrayTyID:<br>
   case Type::VectorTyID:<br>
     return ConstantAggregateZero::get(Ty);<br>
+  case Type::TokenTyID:<br>
+    return ConstantTokenNone::get(Ty->getContext());<br>
   default:<br>
     // Function, Label, or Opaque type?<br>
     llvm_unreachable("Cannot create a null constant of that type!");<br>
@@ -1170,6 +1174,17 @@ Constant *ConstantVector::getSplat(unsig<br>
   return get(Elts);<br>
 }<br>
<br>
+ConstantTokenNone *ConstantTokenNone::get(LLVMContext &Context) {<br>
+  LLVMContextImpl *pImpl = Context.pImpl;<br>
+  if (!pImpl->TheNoneToken)<br>
+    pImpl->TheNoneToken = new ConstantTokenNone(Context);<br>
+  return pImpl->TheNoneToken;<br>
+}<br>
+<br>
+/// Remove the constant from the constant table.<br>
+void ConstantTokenNone::destroyConstantImpl() {<br>
+  llvm_unreachable("You can't ConstantTokenNone->destroyConstantImpl()!");<br>
+}<br>
<br>
 // Utility function for determining if a ConstantExpr is a CastOp or not. This<br>
 // can't be inline because we don't want to #include Instruction.h into<br>
@@ -2875,6 +2890,11 @@ Value *ConstantFP::handleOperandChangeIm<br>
   llvm_unreachable("Unsupported class for handleOperandChange()!");<br>
 }<br>
<br>
+Value *ConstantTokenNone::handleOperandChangeImpl(Value *From, Value *To,<br>
+                                                  Use *U) {<br>
+  llvm_unreachable("Unsupported class for handleOperandChange()!");<br>
+}<br>
+<br>
 Value *UndefValue::handleOperandChangeImpl(Value *From, Value *To, Use *U) {<br>
   llvm_unreachable("Unsupported class for handleOperandChange()!");<br>
 }<br>
<br>
Modified: llvm/trunk/lib/IR/LLVMContextImpl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.cpp?rev=252811&r1=252810&r2=252811&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.cpp?rev=252811&r1=252810&r2=252811&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/IR/LLVMContextImpl.cpp (original)<br>
+++ llvm/trunk/lib/IR/LLVMContextImpl.cpp Wed Nov 11 15:57:16 2015<br>
@@ -21,6 +21,7 @@ using namespace llvm;<br>
<br>
 LLVMContextImpl::LLVMContextImpl(LLVMContext &C)<br>
   : TheTrueVal(nullptr), TheFalseVal(nullptr),<br>
+    TheNoneToken(nullptr),<br>
     VoidTy(C, Type::VoidTyID),<br>
     LabelTy(C, Type::LabelTyID),<br>
     HalfTy(C, Type::HalfTyID),<br>
<br>
Modified: llvm/trunk/lib/IR/LLVMContextImpl.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.h?rev=252811&r1=252810&r2=252811&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.h?rev=252811&r1=252810&r2=252811&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/IR/LLVMContextImpl.h (original)<br>
+++ llvm/trunk/lib/IR/LLVMContextImpl.h Wed Nov 11 15:57:16 2015<br>
@@ -924,6 +924,8 @@ public:<br>
   ConstantInt *TheTrueVal;<br>
   ConstantInt *TheFalseVal;<br>
<br>
+  ConstantTokenNone *TheNoneToken;<br>
+<br>
   // Basic type instances.<br>
   Type VoidTy, LabelTy, HalfTy, FloatTy, DoubleTy, MetadataTy, TokenTy;<br>
   Type X86_FP80Ty, FP128Ty, PPC_FP128Ty, X86_MMXTy;<br>
<br>
Modified: llvm/trunk/lib/Transforms/IPO/MergeFunctions.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/MergeFunctions.cpp?rev=252811&r1=252810&r2=252811&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/MergeFunctions.cpp?rev=252811&r1=252810&r2=252811&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Transforms/IPO/MergeFunctions.cpp (original)<br>
+++ llvm/trunk/lib/Transforms/IPO/MergeFunctions.cpp Wed Nov 11 15:57:16 2015<br>
@@ -656,7 +656,9 @@ int FunctionComparator::cmpConstants(con<br>
   }<br>
<br>
   switch (L->getValueID()) {<br>
-  case Value::UndefValueVal: return TypesRes;<br>
+  case Value::UndefValueVal:<br>
+  case Value::ConstantTokenNoneVal:<br>
+    return TypesRes;<br>
   case Value::ConstantIntVal: {<br>
     const APInt &LInt = cast<ConstantInt>(L)->getValue();<br>
     const APInt &RInt = cast<ConstantInt>(R)->getValue();<br>
<br>
Modified: llvm/trunk/test/Assembler/token.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/token.ll?rev=252811&r1=252810&r2=252811&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/token.ll?rev=252811&r1=252810&r2=252811&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/Assembler/token.ll (original)<br>
+++ llvm/trunk/test/Assembler/token.ll Wed Nov 11 15:57:16 2015<br>
@@ -4,3 +4,8 @@<br>
<br>
 ; CHECK: declare void @llvm.token.foobar(token)<br>
 declare void @llvm.token.foobar(token)<br>
+<br>
+define void @f() {<br>
+  call void @llvm.token.foobar(token none)<br>
+  ret void<br>
+}<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>