Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed bug with dynamic variables escaping static scopes getting diffe… #60

Merged
merged 1 commit into from
Dec 21, 2023

Conversation

AjayBrahmakshatriya
Copy link
Collaborator

…rent names

BuildIt has had a bug with assimilating equivalent variables for a long time. The bug was very rare but shows up when using coroutines with BuildIt. New sample54 demonstrates the bug.

static void bar(void) {
	static_var<int> x = 0;

	dyn_var<int> y = 0;

	if (y) {
		x = 1;
	} else {
		x = 2;
	}
	// When z is declared, x is in different states
	dyn_var<int> z = x;

	// Executions can now merge, but z is still in different states
	x = 0;

	// this declaration forces executions to merge because static tags are the same
	// merge is triggered by memoization
	dyn_var<int> b;

	// this statement now has issues because z has forked
	dyn_var<int> a = z;
}

would originally produce -

void bar (void) {
  int y_0 = 0;
  if (y_0) {
   int z_1 = 1;
  } else {
   int z_2 = 2;
  }
  int b_2;
  int a_3 = z_1;
}

This happens when the same variable is created with different static tags on separate runs (due to static variable being set inside a branch). This creates a problem when the static var state converges. Since all static variables and static locations are the same, BuildIt happily merges execution from this point onwards. But only one of the two copies of the variable is used which either produces code that doesn't compile or misses updates to variables.

A somewhat simple fix is to identify variables based only on their static location and not the entire tag. This change combined with existing variable hoisting makes sure that the variable is declared upfront and set separately on the two branches. This makes sure that the changes are recorded properly. This simple fix however causes unnecessary merging and hoisting of variables that do not escape the static scope.

As a work around, we now identify variables that escape the scope. This is done by matching the static state at use and decl. Variables that escape static scope get a special metadata. Var Namer then looks for this metadata and any variable with this metadata is identified purely on the basis on static location and not the entire static tag. Thus variables are only merged and hoisted when absolutely necessary.

Finally, this creates a problem with dyn_arr<T> since they are supposed to escape the scope of their declarations. Remember dyn_arr<T> are heap allocated and the constructor is called with a static_var loop. To get around this elements in dyn_arr<T> get another metadata that allows them to escape static scope. These variables are identified on the basis on their entire static tag.

With the changes the sample above now produces -

void bar (void) {
  int z_1;
  int y_0 = 0;
  if (y_0) {
    z_1 = 1;
  } else {
    z_1 = 2;
  }
  int b_2;
  int a_3 = z_1;
}

TODO: Investigate if dyn_arr<T> could have forking issues and fix if necessary.

@AjayBrahmakshatriya AjayBrahmakshatriya merged commit 1a00369 into BuildIt-lang:master Dec 21, 2023
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant