GSoC Project: Make C/C++ not automatically promote memory_order_consume to memory_order_acquire

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

GSoC Project: Make C/C++ not automatically promote memory_order_consume to memory_order_acquire

Akshat Garg
Hello everyone,

We are working on the project to not allow memory_order_consume gets
automatically promoted to memory_order_acquire. In implementing
memory_order_consume, the problem comes when tracing dependencies at the
C/C++ source level. We are first targeting to trace the dependencies only
for the pointer types at C source level. To mark the pointers at C source
level, we thought of introducing a new qualifier _Dependent_ptr, for only
pointer type variables. We believe adding this qualifier will allow us to
trace dependencies and not break any of the pointer optimizations.

For start, we have implemented the _Dependent_ptr qualifier in the GCC C
front-end. The patch is given in this link:
https://github.com/AKG001/gcc/commit/fb4187bc3872a50880159232cf336f0a03505fa8
and given below also.

We have also prepared some testcases for checking whether _Dependent_ptr
parses correctly or not. A simple test case is present on this
https://github.com/AKG001/gcc/commit/193a040df649d773fab5cb5e2698e9729dfd2b97
Some litmus test cases from the document (
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0190r4.pdf) are
present in this commit
https://github.com/AKG001/gcc/commit/b4c3c55b11597bde8ea5b297343ab349caedb6a4
For litmus test cases, the file name convention is: <document name>_<figure
in the document>.c

Full set of testcases are present in this repository
https://github.com/AKG001/test/. The .original files are also present for
each test case.
Command used to generate .original file: ./<build directory where cc1
is>cc1 -fdump-tree-original <file name>.c

We request the community to give us their valuable feedback. Also, let us
know if something is wrong or can be done in a better way.

Thanks,
Akshat

-------------------------------------------------------------------------------------------------------------------------------------------------------
commit fb4187bc3872a50880159232cf336f0a03505fa8
Author: Akshat Garg <[hidden email]>
Date:   Sat Jun 8 15:06:23 2019 +0530

    Add _Dependent_ptr qualifier

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 4057be3..6d37851 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -345,6 +345,7 @@ const struct c_common_resword c_common_reswords[] =
   { "_Alignas", RID_ALIGNAS,   D_CONLY },
   { "_Alignof", RID_ALIGNOF,   D_CONLY },
   { "_Atomic", RID_ATOMIC,    D_CONLY },
+  { "_Dependent_ptr",   RID_DEPENDENT_PTR,  0 },
   { "_Bool", RID_BOOL,      D_CONLY },
   { "_Complex", RID_COMPLEX, 0 },
   { "_Imaginary", RID_IMAGINARY, D_CONLY },
@@ -7845,6 +7846,7 @@ keyword_is_type_qualifier (enum rid keyword)
     case RID_VOLATILE:
     case RID_RESTRICT:
     case RID_ATOMIC:
+    case RID_DEPENDENT_PTR:
       return true;
     default:
       return false;
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 1cf2cae..a4c7e03 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -68,7 +68,7 @@ enum rid
   RID_UNSIGNED, RID_LONG,    RID_CONST, RID_EXTERN,
   RID_REGISTER, RID_TYPEDEF, RID_SHORT, RID_INLINE,
   RID_VOLATILE, RID_SIGNED,  RID_AUTO,  RID_RESTRICT,
-  RID_NORETURN, RID_ATOMIC,
+  RID_NORETURN, RID_ATOMIC, RID_DEPENDENT_PTR,

   /* C extensions */
   RID_COMPLEX, RID_THREAD, RID_SAT,
diff --git a/gcc/c-family/c-format.c b/gcc/c-family/c-format.c
index b10599f..3ac3a21 100644
--- a/gcc/c-family/c-format.c
+++ b/gcc/c-family/c-format.c
@@ -3189,6 +3189,7 @@ check_format_types (const substring_loc &fmt_loc,
   && (TYPE_READONLY (cur_type)
       || TYPE_VOLATILE (cur_type)
       || TYPE_ATOMIC (cur_type)
+                || TYPE_DEPENDENT_PTR (cur_type)
       || TYPE_RESTRICT (cur_type)))
  warning (OPT_Wformat_, "extra type qualifiers in format "
  "argument (argument %d)",
diff --git a/gcc/c-family/c-pretty-print.c b/gcc/c-family/c-pretty-print.c
index 3e25624..e034a8f 100644
--- a/gcc/c-family/c-pretty-print.c
+++ b/gcc/c-family/c-pretty-print.c
@@ -181,6 +181,8 @@ pp_c_cv_qualifiers (c_pretty_printer *pp, int
qualifiers, bool func_type)

   if (qualifiers & TYPE_QUAL_ATOMIC)
     pp_c_ws_string (pp, "_Atomic");
+  if (qualifiers & TYPE_QUAL_DEPENDENT_PTR)
+    pp_c_ws_string (pp, "_Dependent_ptr");
   if (qualifiers & TYPE_QUAL_CONST)
     pp_c_ws_string (pp, func_type ? "__attribute__((const))" : "const");
   if (qualifiers & TYPE_QUAL_VOLATILE)
diff --git a/gcc/c/c-aux-info.c b/gcc/c/c-aux-info.c
index 96bb2e2..6632447 100644
--- a/gcc/c/c-aux-info.c
+++ b/gcc/c/c-aux-info.c
@@ -284,6 +284,8 @@ gen_type (const char *ret_val, tree t, formals_style
style)
  case POINTER_TYPE:
   if (TYPE_ATOMIC (t))
     ret_val = concat ("_Atomic ", ret_val, NULL);
+  if (TYPE_DEPENDENT_PTR (t))
+    ret_val = concat ("_Dependent_ptr ", ret_val, NULL);
   if (TYPE_READONLY (t))
     ret_val = concat ("const ", ret_val, NULL);
   if (TYPE_VOLATILE (t))
@@ -427,6 +429,8 @@ gen_type (const char *ret_val, tree t, formals_style
style)
     }
   if (TYPE_ATOMIC (t))
     ret_val = concat ("_Atomic ", ret_val, NULL);
+  if (TYPE_DEPENDENT_PTR (t))
+    ret_val = concat ("_Dependent_ptr ", ret_val, NULL);
   if (TYPE_READONLY (t))
     ret_val = concat ("const ", ret_val, NULL);
   if (TYPE_VOLATILE (t))
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 87ce853..91f0140 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -4540,6 +4540,7 @@ shadow_tag_warned (const struct c_declspecs
*declspecs, int warned)
    && (declspecs->const_p
        || declspecs->volatile_p
        || declspecs->atomic_p
+       || declspecs->dependent_ptr_p
        || declspecs->restrict_p
        || declspecs->address_space))
     {
@@ -4668,6 +4669,7 @@ quals_from_declspecs (const struct c_declspecs *specs)
        | (specs->volatile_p ? TYPE_QUAL_VOLATILE : 0)
        | (specs->restrict_p ? TYPE_QUAL_RESTRICT : 0)
        | (specs->atomic_p ? TYPE_QUAL_ATOMIC : 0)
+               | (specs->dependent_ptr_p ? TYPE_QUAL_DEPENDENT_PTR : 0)
        | (ENCODE_QUAL_ADDR_SPACE (specs->address_space)));
   gcc_assert (!specs->type
       && !specs->decl_attr
@@ -5833,6 +5835,7 @@ grokdeclarator (const struct c_declarator *declarator,
   int restrictp;
   int volatilep;
   int atomicp;
+  int dependent_ptrp;
   int type_quals = TYPE_UNQUALIFIED;
   tree name = NULL_TREE;
   bool funcdef_flag = false;
@@ -5999,6 +6002,7 @@ grokdeclarator (const struct c_declarator *declarator,
   restrictp = declspecs->restrict_p + TYPE_RESTRICT (element_type);
   volatilep = declspecs->volatile_p + TYPE_VOLATILE (element_type);
   atomicp = declspecs->atomic_p + TYPE_ATOMIC (element_type);
+  dependent_ptrp = declspecs->dependent_ptr_p + TYPE_DEPENDENT_PTR
(element_type);
   as1 = declspecs->address_space;
   as2 = TYPE_ADDR_SPACE (element_type);
   address_space = ADDR_SPACE_GENERIC_P (as1)? as2 : as1;
@@ -6011,6 +6015,8 @@ grokdeclarator (const struct c_declarator *declarator,
     pedwarn_c90 (loc, OPT_Wpedantic, "duplicate %<volatile%>");
   if (atomicp > 1)
     pedwarn_c90 (loc, OPT_Wpedantic, "duplicate %<_Atomic%>");
+  if (dependent_ptrp > 1)
+    pedwarn_c90 (loc, OPT_Wpedantic, "duplicate %<_Dependent_ptr%>");

   if (!ADDR_SPACE_GENERIC_P (as1) && !ADDR_SPACE_GENERIC_P (as2) && as1 !=
as2)
     error_at (loc, "conflicting named address spaces (%s vs %s)",
@@ -6027,6 +6033,7 @@ grokdeclarator (const struct c_declarator *declarator,
  | (restrictp ? TYPE_QUAL_RESTRICT : 0)
  | (volatilep ? TYPE_QUAL_VOLATILE : 0)
  | (atomicp ? TYPE_QUAL_ATOMIC : 0)
+     | (dependent_ptrp ? TYPE_QUAL_DEPENDENT_PTR : 0)
  | ENCODE_QUAL_ADDR_SPACE (address_space));
   if (type_quals != TYPE_QUALS (element_type))
     orig_qual_type = NULL_TREE;
@@ -6038,6 +6045,13 @@ grokdeclarator (const struct c_declarator
*declarator,
   if (declspecs->atomic_p && TREE_CODE (type) == ARRAY_TYPE)
     error_at (loc, "%<_Atomic%>-qualified array type");

+  /* Applying the _Dependent_ptr qualifier to an array type (through the
use
+     of typedefs or typeof) must be detected here.  If the qualifier
+     is introduced later, any appearance of applying it to an array is
+     actually applying it to an element of that array.  */
+  if (declspecs->dependent_ptr_p && TREE_CODE (type) == ARRAY_TYPE)
+    error_at (loc, "%<_Dependent_ptr%>-qualified array type");
+
   /* Warn about storage classes that are invalid for certain
      kinds of declarations (parameters, typenames, etc.).  */

@@ -7209,7 +7223,11 @@ grokdeclarator (const struct c_declarator
*declarator,
  /* It's a variable.  */
  /* An uninitialized decl with `extern' is a reference.  */
  int extern_ref = !initialized && storage_class == csc_extern;
-
+
+ /* _Dependent_ptr qualifier only reserved for pointer type variable */
+ if ((type_quals & TYPE_QUAL_DEPENDENT_PTR) && (!POINTER_TYPE_P (type)))
+  error_at (loc, "invalid use of %<_Dependent_ptr%>");
+
  type = c_build_qualified_type (type, type_quals, orig_qual_type,
        orig_qual_indirect);

@@ -10172,6 +10190,12 @@ declspecs_add_qual (location_t loc,
       prev_loc = specs->locations[cdw_atomic];
       specs->locations[cdw_atomic] = loc;
       break;
+    case RID_DEPENDENT_PTR:
+      dupe = specs->dependent_ptr_p;
+      specs->dependent_ptr_p = true;
+      prev_loc = specs->locations[cdw_dependent_ptr];
+      specs->locations[cdw_dependent_ptr] = loc;
+      break;
     default:
       gcc_unreachable ();
     }
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 84ee576..19412d2 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -498,6 +498,7 @@ c_keyword_starts_typename (enum rid keyword)
     case RID_TYPEOF:
     case RID_CONST:
     case RID_ATOMIC:
+    case RID_DEPENDENT_PTR:
     case RID_VOLATILE:
     case RID_RESTRICT:
     case RID_ATTRIBUTE:
@@ -601,6 +602,7 @@ c_token_is_qualifier (c_token *token)
  case RID_RESTRICT:
  case RID_ATTRIBUTE:
  case RID_ATOMIC:
+   case RID_DEPENDENT_PTR:
   return true;
  default:
   return false;
@@ -682,6 +684,7 @@ c_token_starts_declspecs (c_token *token)
  case RID_SAT:
  case RID_ALIGNAS:
  case RID_ATOMIC:
+   case RID_DEPENDENT_PTR:
  case RID_AUTO_TYPE:
   return true;
  default:
@@ -2860,6 +2863,11 @@ c_parser_declspecs (c_parser *parser, struct
c_declspecs *specs,
   else
     declspecs_add_qual (loc, specs, value);
   break;
+   case RID_DEPENDENT_PTR:
+      attrs_ok = true;
+      declspecs_add_qual (loc, specs, c_parser_peek_token (parser)->value);
+      c_parser_consume_token (parser);
+      break;
  case RID_CONST:
  case RID_VOLATILE:
  case RID_RESTRICT:
@@ -4270,6 +4278,7 @@ c_parser_attribute_any_word (c_parser *parser)
  case RID_TRANSACTION_ATOMIC:
  case RID_TRANSACTION_CANCEL:
  case RID_ATOMIC:
+   case RID_DEPENDENT_PTR:
  case RID_AUTO_TYPE:
  case RID_INT_N_0:
  case RID_INT_N_1:
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index 346f46a..7c67a63 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -279,6 +279,7 @@ enum c_declspec_word {
   cdw_volatile,
   cdw_restrict,
   cdw_atomic,
+  cdw_dependent_ptr,
   cdw_saturating,
   cdw_alignas,
   cdw_address_space,
@@ -387,6 +388,8 @@ struct c_declspecs {
   BOOL_BITFIELD restrict_p : 1;
   /* Whether "_Atomic" was specified.  */
   BOOL_BITFIELD atomic_p : 1;
+  /* Whether "_Dependent_ptr" was specified.  */
+  BOOL_BITFIELD dependent_ptr_p : 1;
   /* Whether "_Sat" was specified.  */
   BOOL_BITFIELD saturating_p : 1;
   /* Whether any alignment specifier (even with zero alignment) was
diff --git a/gcc/print-tree.c b/gcc/print-tree.c
index 81b66a1..68b210d 100644
--- a/gcc/print-tree.c
+++ b/gcc/print-tree.c
@@ -334,6 +334,8 @@ print_node (FILE *file, const char *prefix, tree node,
int indent,
     fputs (" readonly", file);
   if (TYPE_P (node) && TYPE_ATOMIC (node))
     fputs (" atomic", file);
+  if (TYPE_P (node) && TYPE_DEPENDENT_PTR (node))
+    fputs (" dependent_ptr", file);
   if (!TYPE_P (node) && TREE_CONSTANT (node))
     fputs (" constant", file);
   else if (TYPE_P (node) && TYPE_SIZES_GIMPLIFIED (node))
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index 26cfa7e..20d6b31 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -546,7 +546,8 @@ enum cv_qualifier {
   TYPE_QUAL_CONST    = 0x1,
   TYPE_QUAL_VOLATILE = 0x2,
   TYPE_QUAL_RESTRICT = 0x4,
-  TYPE_QUAL_ATOMIC   = 0x8
+  TYPE_QUAL_ATOMIC   = 0x8,
+  TYPE_QUAL_DEPENDENT_PTR = 0x10
 };

 /* Standard named or nameless data types of the C compiler.  */
@@ -570,6 +571,8 @@ enum tree_index {
   TI_ATOMICDI_TYPE,
   TI_ATOMICTI_TYPE,

+  TI_DEPENDENT_PTR,
+
   TI_UINT16_TYPE,
   TI_UINT32_TYPE,
   TI_UINT64_TYPE,
@@ -973,7 +976,8 @@ struct GTY(()) tree_base {
       unsigned user_align : 1;
       unsigned nameless_flag : 1;
       unsigned atomic_flag : 1;
-      unsigned spare0 : 3;
+      unsigned dependent_ptr_flag : 1;
+      unsigned spare0 : 2;

       unsigned spare1 : 8;

diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
index 455579c..449906c 100644
--- a/gcc/tree-pretty-print.c
+++ b/gcc/tree-pretty-print.c
@@ -1464,6 +1464,8 @@ dump_generic_node (pretty_printer *pp, tree node, int
spc, dump_flags_t flags,

  if (quals & TYPE_QUAL_ATOMIC)
   pp_string (pp, "atomic ");
+   if (quals & TYPE_QUAL_DEPENDENT_PTR)
+      pp_string (pp, "dependent_ptr ");
  if (quals & TYPE_QUAL_CONST)
   pp_string (pp, "const ");
  else if (quals & TYPE_QUAL_VOLATILE)
@@ -1816,6 +1818,8 @@ dump_generic_node (pretty_printer *pp, tree node, int
spc, dump_flags_t flags,

  if (quals & TYPE_QUAL_ATOMIC)
   pp_string (pp, "atomic ");
+ if (quals & TYPE_QUAL_DEPENDENT_PTR)
+          pp_string (pp, "dependent_ptr ");
  if (quals & TYPE_QUAL_CONST)
   pp_string (pp, "const ");
  if (quals & TYPE_QUAL_VOLATILE)
diff --git a/gcc/tree.c b/gcc/tree.c
index 43ce44f..4bc3c8e 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -6333,6 +6333,7 @@ set_type_quals (tree type, int type_quals)
   TYPE_READONLY (type) = (type_quals & TYPE_QUAL_CONST) != 0;
   TYPE_VOLATILE (type) = (type_quals & TYPE_QUAL_VOLATILE) != 0;
   TYPE_RESTRICT (type) = (type_quals & TYPE_QUAL_RESTRICT) != 0;
+  TYPE_DEPENDENT_PTR (type) = (type_quals & TYPE_QUAL_DEPENDENT_PTR) != 0;
   TYPE_ATOMIC (type) = (type_quals & TYPE_QUAL_ATOMIC) != 0;
   TYPE_ADDR_SPACE (type) = DECODE_QUAL_ADDR_SPACE (type_quals);
 }
diff --git a/gcc/tree.h b/gcc/tree.h
index 5b50941..1e712dc 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -2051,6 +2051,9 @@ extern machine_mode vector_type_mode (const_tree);
 /* Nonzero in a type considered atomic as a whole.  */
 #define TYPE_ATOMIC(NODE) (TYPE_CHECK (NODE)->base.u.bits.atomic_flag)

+/* Nonzero in a type considered dependent_ptr as a whole.  */
+#define TYPE_DEPENDENT_PTR(NODE) (TYPE_CHECK
(NODE)->base.u.bits.dependent_ptr_flag)
+
 /* Means this type is const-qualified.  */
 #define TYPE_READONLY(NODE) (TYPE_CHECK (NODE)->base.readonly_flag)

@@ -2081,6 +2084,7 @@ extern machine_mode vector_type_mode (const_tree);
   ((int) ((TYPE_READONLY (NODE) * TYPE_QUAL_CONST) \
   | (TYPE_VOLATILE (NODE) * TYPE_QUAL_VOLATILE) \
   | (TYPE_ATOMIC (NODE) * TYPE_QUAL_ATOMIC) \
+  | (TYPE_DEPENDENT_PTR (NODE) * TYPE_QUAL_DEPENDENT_PTR)   \
   | (TYPE_RESTRICT (NODE) * TYPE_QUAL_RESTRICT) \
   | (ENCODE_QUAL_ADDR_SPACE (TYPE_ADDR_SPACE (NODE)))))

@@ -2089,6 +2093,7 @@ extern machine_mode vector_type_mode (const_tree);
   ((int) ((TYPE_READONLY (NODE) * TYPE_QUAL_CONST) \
   | (TYPE_VOLATILE (NODE) * TYPE_QUAL_VOLATILE) \
   | (TYPE_ATOMIC (NODE) * TYPE_QUAL_ATOMIC) \
+  | (TYPE_DEPENDENT_PTR (NODE) * TYPE_QUAL_DEPENDENT_PTR)   \
   | (TYPE_RESTRICT (NODE) * TYPE_QUAL_RESTRICT)))

 /* The same as TYPE_QUALS without the address space and atomic
@@ -3877,6 +3882,8 @@ tree_strip_any_location_wrapper (tree exp)
 #define atomicDI_type_node global_trees[TI_ATOMICDI_TYPE]
 #define atomicTI_type_node global_trees[TI_ATOMICTI_TYPE]

+#define dependent_ptrTI_type_node global_trees[TI_DEPENDENT_PTR]
+
 #define uint16_type_node global_trees[TI_UINT16_TYPE]
 #define uint32_type_node global_trees[TI_UINT32_TYPE]
 #define uint64_type_node global_trees[TI_UINT64_TYPE]
--------------------------------------------------------------------------------------------------------------------------------------------------------------