Hi,

Can the gatekeeper review the changes to WHIRL SSA and WHIRL CFG? This patch
includes:
* Some format change
* Add interface to CFG to update its statement list
* Add volatile support to WSSA

-- 
Regards,
Lai Jian-Xin
Index: be/com/wssa_wn.cxx
===================================================================
--- be/com/wssa_wn.cxx	(revision 3402)
+++ be/com/wssa_wn.cxx	(working copy)
@@ -50,8 +50,7 @@
 //===================================================================
 
 BOOL
-WN_has_node(const WN* wn, WSSA_NODE_KIND nkind)
-{
+WN_has_node(const WN* wn, WSSA_NODE_KIND nkind) {
   switch (nkind) {
     case WSSA_PHI:
       return WN_has_phi(wn);
@@ -68,8 +67,7 @@
 }
 
 BOOL
-WN_has_phi(const WN* wn) 
-{
+WN_has_phi(const WN* wn) {
   OPERATOR opr = WN_operator(wn);
   switch (opr) {
     case OPR_IF:
@@ -84,8 +82,7 @@
 }
 
 BOOL
-WN_has_chi(const WN* wn) 
-{
+WN_has_chi(const WN* wn) {
   OPERATOR opr = WN_operator(wn);
   switch (opr) {
     case OPR_FUNC_ENTRY:  // entry chi
@@ -118,8 +115,7 @@
 }
 
 BOOL
-WN_has_mu(const WN* wn) 
-{
+WN_has_mu(const WN* wn) {
   OPERATOR opr = WN_operator(wn);
   switch (opr) {
     case OPR_ASM_STMT:
@@ -145,8 +141,7 @@
 }
 
 BOOL
-WN_has_ver(const WN* wn) 
-{
+WN_has_ver(const WN* wn) {
   OPERATOR opr = WN_operator(wn);
   switch (opr) {
     case OPR_LDID:
@@ -160,8 +155,7 @@
 }
 
 BOOL
-WN_def_ver(const WN* wn)
-{
+WN_def_ver(const WN* wn) {
   OPERATOR opr = WN_operator(wn);
   switch (opr) {
     case OPR_STID:
@@ -173,8 +167,7 @@
 }
 
 BOOL
-WN_use_ver(const WN* wn)
-{
+WN_use_ver(const WN* wn) {
   OPERATOR opr = WN_operator(wn);
   switch (opr) {
     case OPR_LDID:
@@ -185,5 +178,34 @@
   }
 }
 
+BOOL
+WN_is_volatile(const WN* wn) {
+  if (WN_ty(wn) != 0 && TY_is_volatile(WN_ty(wn)))
+    return TRUE;
+  else if (WN_has_sym(wn) &&
+           WN_st(wn) != NULL &&
+           ST_class(WN_st(wn)) == CLASS_VAR &&
+           TY_is_volatile(ST_type(WN_st(wn))))
+    return TRUE;
+  else
+    return FALSE;
+}
+
+BOOL
+Tree_is_volatile(const WN* tree) {
+  OPCODE opc = WN_opcode(tree);
+  Is_True(OPCODE_is_stmt(opc) || OPCODE_is_expression(opc),
+          ("opcode %s is not stmt or expr", OPCODE_name(opc)));
+
+  if (WN_is_volatile(tree)) {
+    return TRUE;
+  }
+  for (int i=0; i < WN_kid_count(tree); ++i) {
+    if (Tree_is_volatile(WN_kid(tree, i)))
+      return TRUE;
+  }
+  return FALSE;
+}
+
 } /* namespace WSSA */
 
Index: be/com/wssa_sym.cxx
===================================================================
--- be/com/wssa_sym.cxx	(revision 3402)
+++ be/com/wssa_sym.cxx	(working copy)
@@ -108,11 +108,9 @@
     _def_wn(NULL), _def_type(WSSA_UNKNOWN), _ver_flags(0) {
 }
 
-WST_Version_Entry::WST_Version_Entry(const WN* wn, WST_IDX wst_idx, UINT32 ver, WSSA_NODE_KIND type, BOOL zero_ver)
+WST_Version_Entry::WST_Version_Entry(WST_IDX wst_idx, UINT32 ver, const WN* wn, WSSA_NODE_KIND type)
   : _wst_idx(wst_idx), _version(ver), _prev_ver(VER_INVALID),
     _def_wn(wn), _def_type(type), _ver_flags(0) {
-  if (zero_ver)
-    Set_flag(VER_IS_ZERO);
 }
 
 void 
Index: be/com/wn_cfg.h
===================================================================
--- be/com/wn_cfg.h	(revision 3402)
+++ be/com/wn_cfg.h	(working copy)
@@ -102,6 +102,11 @@
   WN* Last_stmt() const;
   BOOL Is_empty() const;
 
+  // update the stmt inside the Container
+  void Insert_before(WN* before, WN* stmt);
+  void Insert_after(WN* after, WN* stmt);
+  void Remove_stmt(WN* stmt);
+
   // iterators to traverse the statements
   iterator begin() { return iterator(First_stmt(), this); }
   iterator end()   { return iterator(NULL, this);        }
Index: be/com/cfg_base.h
===================================================================
--- be/com/cfg_base.h	(revision 3402)
+++ be/com/cfg_base.h	(working copy)
@@ -98,8 +98,14 @@
   STMT First_stmt() const  { return _stmts.First_stmt(); }
   STMT Last_stmt() const   { return _stmts.Last_stmt();  }
   BOOL Is_empty() const    { return _stmts.Is_empty();   }
+  void Insert_before(STMT before, STMT stmt) {
+    _stmts.Insert_before(before, stmt);
+  }
+  void Insert_after(STMT after, STMT stmt) {
+    _stmts.Insert_after(after, stmt);
+  }
+  void Remove_stmt(STMT stmt)   { _stmts.Remove_stmt(stmt); }
 
-
   // preds/succs related methods
   void Add_pred(BB_NODE* pred)  { _preds.push_back(pred);   }
   void Add_succ(BB_NODE* succ)  { _succs.push_back(succ);   }
@@ -613,7 +619,11 @@
 
   // node operations
   BB_NODE* Create_node()           { return _node_container.Create_node(_cfg_pool); }
-  void Delete_node(BB_NODE* node)  { _node_container.Delete_node(node, _cfg_pool);  }
+  void Delete_node(BB_NODE* node)  {
+    Disconnect_node(node);  // remove all edges on the node
+    Disconnect_all_stmt_in_node(node);  // disconnect all stmts in the node
+    _node_container.Delete_node(node, _cfg_pool);  // delete the node
+  }
   UINT32 Get_max_id() const        { return _node_container.Get_max_id(); }
   BB_NODE* Get_node(UINT32 id)     { return _node_container.Get_node(id); }
   BB_NODE* Get_dummy_entry() const { return _dummy_entry; }
@@ -676,6 +686,29 @@
     return _stmt_mapper.Get_stmt_node(stmt);
   }
 
+  // insert/delete stmt from node
+  void Insert_before(STMT before, STMT stmt) {
+    Is_True(before != NULL && stmt != NULL, ("insert point or stmt is null"));
+    BB_NODE* node = Get_stmt_node(before);
+    Is_True(node != NULL, ("can not find BB for insert point"));
+    node->Insert_before(before, stmt);
+    Connect_stmt_node(stmt, node);
+  }
+  void Insert_after(STMT after, STMT stmt) {
+    Is_True(after != NULL && stmt != NULL, ("insert point or stmt is null"));
+    BB_NODE* node = Get_stmt_node(after);
+    Is_True(node != NULL, ("can not find BB for insert point"));
+    node->Insert_after(after, stmt);
+    Connect_stmt_node(stmt, node);
+  }
+  void Remove_stmt(STMT stmt) {
+    Is_True(stmt != NULL, ("stmt is null"));
+    BB_NODE* node = Get_stmt_node(stmt);
+    Is_True(node != NULL, ("can not find BB for stmt"));
+    node->Remove_stmt(stmt);
+    Disconnect_stmt_node(stmt, node);
+  }
+
   // DFS iterators
   dfs_fwd_itrator Dfs_fwd_begin() { dfs_fwd_itrator it(Get_dummy_entry(), Get_max_id()); return it;  }
   dfs_fwd_itrator Dfs_fwd_end()   { dfs_fwd_itrator it(NULL, 0); return it; }
Index: be/com/wn_cfg.cxx
===================================================================
--- be/com/wn_cfg.cxx	(revision 3402)
+++ be/com/wn_cfg.cxx	(working copy)
@@ -78,6 +78,87 @@
 }
 
 void
+WN_STMT_CONTAINER::Insert_before(WN* before, WN* stmt) {
+  Is_True(before != NULL, ("invalid before stmt"));
+  Is_True(stmt != NULL, ("invalid stmt"));
+  Is_True(OPERATOR_is_stmt(WN_operator(stmt)), ("invalid stmt"));
+  FmtAssert(before != _extra_stmt, ("TODO: support insert before extra stmt"));
+  FmtAssert(WN_operator(before) != OPR_LABEL, ("can not insert before label"));
+
+#ifdef Is_True_On
+  WN* wn = NULL;
+  for (wn = _first_stmt; wn != _last_stmt; wn = WN_next(wn)) {
+    if (wn == before)
+      break;
+  }
+  Is_True(before == wn, ("can not find insert position"));
+#endif
+
+  if (before == _first_stmt) {
+    _first_stmt = stmt;
+  }
+}
+
+void
+WN_STMT_CONTAINER::Insert_after(WN* after, WN* stmt) {
+  Is_True(after != NULL, ("invalid after stmt"));
+  Is_True(stmt != NULL, ("invalid stmt"));
+  Is_True(OPERATOR_is_stmt(WN_operator(stmt)), ("invalid stmt"));
+  Is_True(!OPERATOR_is_scf(WN_operator(after)), ("TODO: after is scf"));
+  Is_True(WN_operator(after) != OPR_TRUEBR &&
+          WN_operator(after) != OPR_FALSEBR &&
+          WN_operator(after) != OPR_GOTO &&
+          WN_operator(after) != OPR_AGOTO &&
+          WN_operator(after) != OPR_CASEGOTO &&
+          WN_operator(after) != OPR_COMPGOTO &&
+          WN_operator(after) != OPR_GOTO_OUTER_BLOCK &&
+          WN_operator(after) != OPR_RETURN &&
+          WN_operator(after) != OPR_RETURN_VAL &&
+          WN_operator(after) != OPR_XGOTO, ("TODO: after is jump"));
+  FmtAssert(after != _extra_stmt, ("TODO: support insert after extra stmt"));
+
+#ifdef Is_True_On
+  WN* wn = NULL;
+  for (wn = _first_stmt; wn != _last_stmt; wn = WN_next(wn)) {
+    if (wn == after)
+      break;
+  }
+  Is_True(after == wn, ("can not find insert position"));
+#endif
+
+  if (after == _last_stmt) {
+    _last_stmt = stmt;
+  }
+}
+
+void
+WN_STMT_CONTAINER::Remove_stmt(WN* stmt) {
+  Is_True(stmt != NULL, ("invalid stmt"));
+  FmtAssert(stmt != _extra_stmt, ("TODO: support remove extra stmt"));
+
+#ifdef Is_True_On
+  WN* wn = NULL;
+  for (wn = _first_stmt; wn != _last_stmt; wn = WN_next(wn)) {
+    if (wn == stmt)
+      break;
+  }
+  Is_True(stmt == wn, ("can not find wn"));
+#endif
+
+  if (_first_stmt != _last_stmt) {
+    if (stmt == _first_stmt)
+      _first_stmt = WN_next(_first_stmt);
+    if (stmt == _last_stmt)
+      _last_stmt = WN_prev(_last_stmt);
+  }
+  else {
+    FmtAssert(stmt == _first_stmt, ("can not find wn"));
+    FmtAssert(_extra_stmt == NULL, ("extra stmt is not NULL"));
+    _first_stmt = _last_stmt = NULL;
+  }
+}
+
+void
 WN_STMT_CONTAINER::Print(FILE* fp, INT32 dump_flag) const {
   if (dump_flag & DUMP_AIR) {
     for (WN* wn = First_stmt(); wn != NULL; wn = Next_stmt(wn)) {
@@ -439,12 +520,15 @@
   _current_bb = cfg.Create_node();
   cfg.Add_entry_node(_current_bb);
   Add_block(cfg, WN_func_body(wn));
+
+  // put FUNC_ENTRY into dummy entry
+  Add_stmt(cfg, cfg.Get_dummy_entry(), wn);
 }
 
 //===================================================================
 // Add_altentry: handle ALTENTRY
 //   STMT0 --> BB0 (must be GOTO/RETURN)
-//   FUNC_ENTRY --> BB1 (BB1 don't have other preds than dummy_entry
+//   ALTENTRY --> BB1 (BB1 don't have other preds than dummy_entry
 //     [kid0..n-1] IDNAME --> ignore
 //===================================================================
 void
@@ -454,9 +538,12 @@
   Is_True(_current_bb != NULL, ("Current BB is NULL"));
   Is_True(_current_bb->Get_preds_count() == 0, ("Current BB has predecessors"));
 
-  // put BODY into BB1
+  // create new BB for ALTENTRY, connect new bb with dummy entry
   _current_bb = cfg.Create_node();
   cfg.Add_entry_node(_current_bb);
+
+  // put ALTENTRY into _current_bb
+  Add_stmt(cfg, _current_bb, wn);
 }
 
 //===================================================================
@@ -913,7 +1000,13 @@
   Is_True(stmt != NULL, ("wn is NULL"));
 
   OPERATOR opr = WN_operator(stmt);
-  Is_True(opr != OPR_FUNC_ENTRY && opr != OPR_ALTENTRY, ("stmt is ENTRY"));
+  if (opr == OPR_FUNC_ENTRY) {
+    Is_True(bb == cfg.Get_dummy_entry(), ("FUNC_ENTRY can only be in dummy entry"));
+  }
+  if (opr == OPR_ALTENTRY) {
+    Is_True(bb->Get_preds_count() == 1 &&
+            *(bb->Pred_begin()) == cfg.Get_dummy_entry(), ("ALTENTRY can only have the dummy entry as it pred."));
+  }
 
   bb->Add_stmt(stmt);
   cfg.Connect_stmt_node(stmt, bb);
Index: be/com/wssa_wn.h
===================================================================
--- be/com/wssa_wn.h	(revision 3402)
+++ be/com/wssa_wn.h	(working copy)
@@ -63,6 +63,13 @@
 // return TRUE if the version can be used by the WN (LDID/LDBITS)
 BOOL WN_use_ver(const WN* wn);
 
+// return TRUE if WN or ST used in WN node is volatile
+BOOL WN_is_volatile(const WN* wn);
+
+// return TRUE if WN or ST used in WN tree is volatile
+// tree must be statement or expression
+BOOL Tree_is_volatile(const WN* tree);
+
 } /* namespace WSSA */
 
 #endif  /* wssa_wn_INCLUDED */
Index: be/com/wssa_sym.h
===================================================================
--- be/com/wssa_sym.h	(revision 3402)
+++ be/com/wssa_sym.h	(working copy)
@@ -207,7 +207,8 @@
 
 // Version flag
 enum VER_FLAG {
-  VER_IS_ZERO = 0x1,   // zero version
+  VER_IS_ZERO = 0x1,     // zero version
+  VER_IS_VOLATILE = 0x2, // def or use is volatile
 };
 
 // WSSA version entry
@@ -226,6 +227,11 @@
   };
   // TODO: FSA, POINTS_TO
 
+private:
+  void Set_flag(VER_FLAG flag)    { _ver_flags |= flag; }
+  void Reset_flag(VER_FLAG flag)  { _ver_flags &= !flag; }
+  BOOL Is_flag_set(VER_FLAG flag) const { return (_ver_flags & flag) == flag; }
+
 public:
   // these routines are for IO only
   void Set_flags(INT32 flags)     { _flags = flags; }
@@ -233,8 +239,8 @@
 
 public:
   WST_Version_Entry();
-  WST_Version_Entry(const WN* def_wn, WST_IDX wst_idx, UINT32 ver,
-                    WSSA_NODE_KIND def_type, BOOL zero_ver);
+  WST_Version_Entry(WST_IDX wst_idx, UINT32 ver,
+                    const WN* def_wn, WSSA_NODE_KIND def_type);
 
 public:
   WST_IDX Get_wst() const   { return _wst_idx; }
@@ -252,10 +258,14 @@
   WSSA_NODE_KIND Get_def_type() const    { return (WSSA_NODE_KIND)_def_type; }
   void Set_def_type(WSSA_NODE_KIND type) { _def_type = type; }
 
-  void Set_flag(VER_FLAG flag)    { _ver_flags |= flag; }
-  void Reset_flag(VER_FLAG flag)  { _ver_flags &= !flag; }
-  BOOL Is_flag_set(VER_FLAG flag) const { return (_ver_flags & flag) == flag; }
+  void Set_zero()      { Set_flag(VER_IS_ZERO);   }
+  void Reset_zero()    { Reset_flag(VER_IS_ZERO); }
+  BOOL Is_zero() const { return Is_flag_set(VER_IS_ZERO); }
 
+  void Set_volatile()      { Set_flag(VER_IS_VOLATILE);   }
+  void Reset_volatile()    { Reset_flag(VER_IS_VOLATILE); }
+  BOOL Is_volatile() const { return Is_flag_set(VER_IS_VOLATILE); }
+
 public:
   void Print(FILE* fp = stdout) const;
 };
Index: be/com/wssa_mgr.cxx
===================================================================
--- be/com/wssa_mgr.cxx	(revision 3402)
+++ be/com/wssa_mgr.cxx	(working copy)
@@ -506,6 +506,9 @@
   ST_IDX st_idx = 0;
   switch (sym.Sym_type()) {
   case WST_WHIRL:
+  case WST_PREG:
+  case WST_FIELD:
+  case WST_VSYM:
     st_idx = sym.St_idx();
     break;
   default:
@@ -587,11 +590,15 @@
   VER_IDX idx = (VER_IDX)_ver_table.size();
   _ver_table.push_back(ver);
 
-  if (ver.Get_def_wn() != NULL) {
-    VER_IDX last_ver = wst.Last_ver();
+  VER_IDX last_ver = wst.Last_ver();
+  if (ver.Get_def_wn() != NULL ||          // musy def or may def
+      (last_ver != VER_INVALID &&          // previous def is volatile
+       _ver_table[last_ver].Is_volatile())) {
     _ver_table[idx].Set_prev_ver(last_ver);
     wst.Set_last_ver(idx);
   }
Index: be/com/wssa_mgr.h
===================================================================
--- be/com/wssa_mgr.h	(revision 3402)
+++ be/com/wssa_mgr.h	(working copy)
@@ -353,6 +353,17 @@
       const WST_Version_Entry& ver = _mgr->Get_ver(_cur_ver);
       _def_type = ver.Get_def_type();
       _def_wn = ver.Get_def_wn();
+      if (_def_wn == NULL) {
+        Is_True(_def_type == WSSA_UNKNOWN, ("invalid def type"));
+        // volatile use does not have def
+        // if the previous def is volatile, there is no def for current use
+        VER_IDX prev_ver = ver.Prev_ver();
+        Is_True(ver.Is_volatile() == TRUE ||
+                (prev_ver != VER_INVALID && 
+                 _mgr->Get_ver(prev_ver).Is_volatile() == TRUE), 
+                ("cur use or prev def is not volatile"));
+        continue;
+      }
       Is_True(_def_wn != NULL && _def_type != WSSA_UNKNOWN, ("invalid def wn"));
 
       if (_wn_visited[(INTPTR)_def_wn] == true)
------------------------------------------------------------------------------
Beautiful is writing same markup. Internet Explorer 9 supports
standards for HTML5, CSS3, SVG 1.1,  ECMAScript5, and DOM L2 & L3.
Spend less time writing and  rewriting code and more time creating great
experiences on the web. Be a part of the beta today
http://p.sf.net/sfu/msIE9-sfdev2dev
_______________________________________________
Open64-devel mailing list
Open64-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/open64-devel

Reply via email to