-
Notifications
You must be signed in to change notification settings - Fork 163
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Optimize true/false conditions when coding if-statements
We already had some code which "optimized" some if-statements with one or two conditions, where one or both were constant equal to `true` or `false`. We skipped branches whose condition was always `false`. However, we did not use the `IntrIgnoring` mechanism for that. Thus, such code would still trigger warnings if it contained undefined globals, e.g. gap> f:=function() if false then undefined_global(); fi; end;; Syntax warning: Unbound global variable f:=function() if false then undefined_global(); fi; end;; ^ This can be viewed as a feature, or as a bug, depending on view point. A reason to consider it a "bug" (or at least an undesirable feature) is when using global constants to only conditionally execute code, such as this: if IsHPCGAP then UNLOCK(lock); fi; This code is optimized away in regular GAP, but still triggers a warning during parsing. With this commit, we change how we deal with true/false conditions in if-statements, by making use of the `IntrIgnoring` mechanism. This avoids the warnings about globals in the examples above. It also has the side effect of being "better" at optimizing away branches of an if-statement which can never be executed.
- Loading branch information
Showing
8 changed files
with
194 additions
and
98 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
# | ||
# Test the GAP function coder | ||
# | ||
gap> START_TEST("coding.tst"); | ||
|
||
# | ||
# Test coding of if-statements in which some conditions are true or false | ||
# | ||
# | ||
|
||
# test if-statements with single branch | ||
gap> f:=function(x) if x then return 1; fi; end;; Display(f); | ||
function ( x ) | ||
if x then | ||
return 1; | ||
fi; | ||
return; | ||
end | ||
gap> f:=function(x) if true then return 1; fi; end;; Display(f); | ||
function ( x ) | ||
return 1; | ||
end | ||
gap> f:=function(x) if false then return 1; fi; end;; Display(f); | ||
function ( x ) | ||
; | ||
return; | ||
end | ||
|
||
# test if-statements with two branches (note that 'else' is equivalent to 'elif true'), | ||
# first condition is neither true nor false | ||
gap> f:=function(x) if x then return 1; else return 2; fi; end;; Display(f); | ||
function ( x ) | ||
if x then | ||
return 1; | ||
else | ||
return 2; | ||
fi; | ||
return; | ||
end | ||
gap> f:=function(x) if x then return 1; elif x then return 2; fi; end;; Display(f); | ||
function ( x ) | ||
if x then | ||
return 1; | ||
elif x then | ||
return 2; | ||
fi; | ||
return; | ||
end | ||
gap> f:=function(x) if x then return 1; elif false then return 2; fi; end;; Display(f); | ||
function ( x ) | ||
if x then | ||
return 1; | ||
fi; | ||
return; | ||
end | ||
|
||
# test if-statements with two branches (note that 'else' is equivalent to 'elif true'), | ||
# first condition is true | ||
gap> f:=function(x) if true then return 1; else return 2; fi; end;; Display(f); | ||
function ( x ) | ||
return 1; | ||
end | ||
gap> f:=function(x) if true then return 1; elif x then return 2; fi; end;; Display(f); | ||
function ( x ) | ||
return 1; | ||
end | ||
gap> f:=function(x) if true then return 1; elif false then return 2; fi; end;; Display(f); | ||
function ( x ) | ||
return 1; | ||
end | ||
|
||
# test if-statements with two branches (note that 'else' is equivalent to 'elif true'), | ||
# first condition is false | ||
gap> f:=function(x) if false then return 1; else return 2; fi; end;; Display(f); | ||
function ( x ) | ||
return 2; | ||
end | ||
gap> f:=function(x) if false then return 1; elif x then return 2; fi; end;; Display(f); | ||
function ( x ) | ||
if x then | ||
return 2; | ||
fi; | ||
return; | ||
end | ||
gap> f:=function(x) if false then return 1; elif false then return 2; fi; end;; Display(f); | ||
function ( x ) | ||
; | ||
return; | ||
end | ||
|
||
# test some if-statements with three branches | ||
gap> f:=function(x) if true then return 1; elif true then return 2; else return 3; fi; end;; Display(f); | ||
function ( x ) | ||
return 1; | ||
end | ||
gap> f:=function(x) if true then return 1; elif x then return 2; else return 3; fi; end;; Display(f); | ||
function ( x ) | ||
return 1; | ||
end | ||
gap> f:=function(x) if x then return 1; elif true then return 2; else return 3; fi; end;; Display(f); | ||
function ( x ) | ||
if x then | ||
return 1; | ||
else | ||
return 2; | ||
fi; | ||
return; | ||
end | ||
gap> f:=function(x) if x then return 1; elif false then return 2; else return 3; fi; end;; Display(f); | ||
function ( x ) | ||
if x then | ||
return 1; | ||
else | ||
return 3; | ||
fi; | ||
return; | ||
end | ||
gap> f:=function(x) if false then return 1; elif true then return 2; else return 3; fi; end;; Display(f); | ||
function ( x ) | ||
return 2; | ||
end | ||
gap> f:=function(x) if false then return 1; elif x then return 2; else return 3; fi; end;; Display(f); | ||
function ( x ) | ||
if x then | ||
return 2; | ||
else | ||
return 3; | ||
fi; | ||
return; | ||
end | ||
|
||
# | ||
gap> STOP_TEST("coding.tst", 1); |
Oops, something went wrong.