From cc519be0772a2dfc49890735799b7ed42107bf50 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= <tseeker@nocternity.net>
Date: Sun, 10 Dec 2017 15:25:51 +0100
Subject: [PATCH] Optimizer - UD chains - Function arguments

Function arguments are the simplest case for UD chains, as they are
immutable.
---
 3rdparty/ebcl |  2 +-
 c-opopt.cc    | 72 ++++++++++++++++++++++++++++++++++++++++++++++++---
 c-opopt.hh    |  7 +++--
 3 files changed, 73 insertions(+), 8 deletions(-)

diff --git a/3rdparty/ebcl b/3rdparty/ebcl
index 53feddb..04726e2 160000
--- a/3rdparty/ebcl
+++ b/3rdparty/ebcl
@@ -1 +1 @@
-Subproject commit 53feddb4ee892f3356c51dc7b8312ffded4d455b
+Subproject commit 04726e20678a1dd8269b33a51e3a3a16d38ddb5b
diff --git a/c-opopt.cc b/c-opopt.cc
index ecf300c..1fff950 100644
--- a/c-opopt.cc
+++ b/c-opopt.cc
@@ -584,8 +584,9 @@ void BUDCAddRecord_(
 
 	od.logger( [&](){
 		T_StringBuilder sb;
-		sb << ( use ? "use " : "def " ) << varId.name << " at "
-			<< n.location( ) << " (";
+		sb << ( use ? "use " : "def " ) << varId.name << "(#"
+			<< ( use ? varRec->uses.size( ) : varRec->defines.size( ) ) - 1
+			<< ") at " << n.location( ) << " (";
 		if ( varId.type == T_OptData::E_UDVarType::GLOBAL ) {
 			sb << "global";
 		} else {
@@ -721,6 +722,45 @@ void BUDCAddEntries_(
 	}
 }
 
+/*----------------------------------------------------------------------------*/
+
+void BUDCLink_(
+		T_OptData::T_VarUseDefine&	var ,
+		const uint32_t			def ,
+		const uint32_t			use ,
+		F_OPLogger const&		logger
+		) noexcept
+{
+	var.uses[ use ].refs.add( def );
+	if ( def != T_HashIndex::INVALID_INDEX ) {
+		var.defines[ def ].refs.add( use );
+	}
+	logger( [&](){
+		T_StringBuilder sb;
+		sb << var.var.name << " (";
+		switch ( var.var.type ) {
+		    case T_OptData::E_UDVarType::GLOBAL:
+			sb << "global";
+			break;
+		    case T_OptData::E_UDVarType::ARGUMENT:
+			sb << "argument of " << var.var.owner;
+			break;
+		    case T_OptData::E_UDVarType::LOCAL:
+			sb << "local variable of " << var.var.owner;
+			break;
+		}
+		sb << ") ";
+		if ( def == T_HashIndex::INVALID_INDEX ) {
+			sb << "UNDEFINED";
+		} else {
+			sb << "DEF " << def;
+		}
+		sb << " USE " << use;
+
+		return sb;
+	} , LL2 );
+}
+
 
 } // namespace <anon>
 
@@ -740,7 +780,8 @@ void T_OptData::buildUseDefineChains(
 		return true;
 	} );
 
-	// Build a table of all variable uses/defines that were identified
+	// Build a per-instruction table of all variable uses/defines that were
+	// identified
 	T_UDEPerInstr_ udPerInstr;
 	auto const& udcEntries{ varUDChains.values( ) };
 	const auto n{ udcEntries.size( ) };
@@ -782,6 +823,31 @@ void T_OptData::buildUseDefineChains(
 	 *	- handle globals by following all edges and terminating at the
 	 * exit node
 	 */
+
+	// Proceed for each symbol
+	for ( auto& sym : varUDChains.values( ) ) {
+		switch ( sym.var.type ) {
+		    case T_OptData::E_UDVarType::GLOBAL:
+#warning TODO
+			break;
+
+		    case T_OptData::E_UDVarType::ARGUMENT: {
+			const auto nDefs{ sym.defines.size( ) };
+			const auto nUses{ sym.uses.size( ) };
+			for ( auto i = 0u ; i < nDefs ; i ++ ) {
+				for ( auto j = 0u ; j < nUses ; j ++ ) {
+					BUDCLink_( sym , i , j , logger );
+				}
+			}
+			break;
+		    }
+
+		    case T_OptData::E_UDVarType::LOCAL:
+#warning TODO
+			break;
+		}
+	}
+
 #if 0
 	// Walk the graph from the entry point until all reachable nodes
 	// have been covered and keeping track of active definitions. When
diff --git a/c-opopt.hh b/c-opopt.hh
index f4467f6..583f817 100644
--- a/c-opopt.hh
+++ b/c-opopt.hh
@@ -116,9 +116,7 @@ struct T_OptData
 
 	// Type of variables used for use/define chains
 	enum class E_UDVarType {
-		GLOBAL ,
-		LOCAL ,
-		ARGUMENT
+		GLOBAL , LOCAL , ARGUMENT
 	};
 
 	// Variable identifier for the U/D chains
@@ -158,7 +156,8 @@ struct T_OptData
 	{
 		uint32_t node;				// Instruction that uses or sets it
 		uint32_t fnIndex;			// Function in which the use/define is located
-		T_AutoArray< uint32_t , 16 > refs;	// Corresponding uses/defines
+		ebcl::T_Set< uint32_t > refs{		// Corresponding uses/defines
+			ebcl::UseTag< ebcl::ArrayBacked< 16 > >( ) };
 	};
 
 	// Use/define chains for a variable