summaryrefslogtreecommitdiff
path: root/compiler/cmm
diff options
context:
space:
mode:
authorklebinger.andreas@gmx.at <klebinger.andreas@gmx.at>2018-01-26 13:07:05 -0500
committerBen Gamari <ben@smart-cactus.org>2018-01-26 14:37:28 -0500
commite7dcc7085315ea8ebc2d6808fde2d9c37fd10c67 (patch)
tree212cf97478384cb7df8a412ba351b52e6e51471a /compiler/cmm
parent52dfb25c400bf1225132fdb8d7c25fa385c8ae3f (diff)
downloadhaskell-e7dcc7085315ea8ebc2d6808fde2d9c37fd10c67.tar.gz
Add ability to parse likely flags for ifs in Cmm.
Adding the ability to parse likely flags in Cmm allows better codegen for cmm files. Test Plan: ci Reviewers: bgamari, simonmar Reviewed By: bgamari Subscribers: rwbarton, thomie, carter GHC Trac Issues: #14672 Differential Revision: https://phabricator.haskell.org/D4316
Diffstat (limited to 'compiler/cmm')
-rw-r--r--compiler/cmm/CmmLex.x12
-rw-r--r--compiler/cmm/CmmParse.y50
2 files changed, 41 insertions, 21 deletions
diff --git a/compiler/cmm/CmmLex.x b/compiler/cmm/CmmLex.x
index a68f155883..691ca5eb28 100644
--- a/compiler/cmm/CmmLex.x
+++ b/compiler/cmm/CmmLex.x
@@ -99,6 +99,10 @@ $white_no_nl+ ;
"&&" { kw CmmT_BoolAnd }
"||" { kw CmmT_BoolOr }
+ "True" { kw CmmT_True }
+ "False" { kw CmmT_False }
+ "likely" { kw CmmT_likely}
+
P@decimal { global_regN (\n -> VanillaReg n VGcPtr) }
R@decimal { global_regN (\n -> VanillaReg n VNonGcPtr) }
F@decimal { global_regN FloatReg }
@@ -180,6 +184,9 @@ data CmmToken
| CmmT_Int Integer
| CmmT_Float Rational
| CmmT_EOF
+ | CmmT_False
+ | CmmT_True
+ | CmmT_likely
deriving (Show)
-- -----------------------------------------------------------------------------
@@ -266,7 +273,10 @@ reservedWordsFM = listToUFM $
( "b512", CmmT_bits512 ),
( "f32", CmmT_float32 ),
( "f64", CmmT_float64 ),
- ( "gcptr", CmmT_gcptr )
+ ( "gcptr", CmmT_gcptr ),
+ ( "likely", CmmT_likely),
+ ( "True", CmmT_True ),
+ ( "False", CmmT_False )
]
tok_decimal span buf len
diff --git a/compiler/cmm/CmmParse.y b/compiler/cmm/CmmParse.y
index 8afbd2f9d9..cf660d274f 100644
--- a/compiler/cmm/CmmParse.y
+++ b/compiler/cmm/CmmParse.y
@@ -299,6 +299,10 @@ import qualified Data.Map as M
'&&' { L _ (CmmT_BoolAnd) }
'||' { L _ (CmmT_BoolOr) }
+ 'True' { L _ (CmmT_True ) }
+ 'False' { L _ (CmmT_False) }
+ 'likely'{ L _ (CmmT_likely)}
+
'CLOSURE' { L _ (CmmT_CLOSURE) }
'INFO_TABLE' { L _ (CmmT_INFO_TABLE) }
'INFO_TABLE_RET'{ L _ (CmmT_INFO_TABLE_RET) }
@@ -629,10 +633,10 @@ stmt :: { CmmParse () }
{ doCall $2 [] $4 }
| '(' formals ')' '=' 'call' expr '(' exprs0 ')' ';'
{ doCall $6 $2 $8 }
- | 'if' bool_expr 'goto' NAME
- { do l <- lookupLabel $4; cmmRawIf $2 l }
- | 'if' bool_expr '{' body '}' else
- { cmmIfThenElse $2 (withSourceNote $3 $5 $4) $6 }
+ | 'if' bool_expr cond_likely 'goto' NAME
+ { do l <- lookupLabel $5; cmmRawIf $2 l $3 }
+ | 'if' bool_expr cond_likely '{' body '}' else
+ { cmmIfThenElse $2 (withSourceNote $4 $6 $5) $7 $3 }
| 'push' '(' exprs0 ')' maybe_body
{ pushStackFrame $3 $5 }
| 'reserve' expr '=' lreg maybe_body
@@ -721,6 +725,12 @@ else :: { CmmParse () }
: {- empty -} { return () }
| 'else' '{' body '}' { withSourceNote $2 $4 $3 }
+cond_likely :: { Maybe Bool }
+ : '(' 'likely' ':' 'True' ')' { Just True }
+ | '(' 'likely' ':' 'False' ')' { Just False }
+ | {- empty -} { Nothing }
+
+
-- we have to write this out longhand so that Happy's precedence rules
-- can kick in.
expr :: { CmmParse CmmExpr }
@@ -1289,11 +1299,11 @@ data BoolExpr
-- ToDo: smart constructors which simplify the boolean expression.
-cmmIfThenElse cond then_part else_part = do
+cmmIfThenElse cond then_part else_part likely = do
then_id <- newBlockId
join_id <- newBlockId
c <- cond
- emitCond c then_id
+ emitCond c then_id likely
else_part
emit (mkBranch join_id)
emitLabel then_id
@@ -1301,38 +1311,38 @@ cmmIfThenElse cond then_part else_part = do
-- fall through to join
emitLabel join_id
-cmmRawIf cond then_id = do
+cmmRawIf cond then_id likely = do
c <- cond
- emitCond c then_id
+ emitCond c then_id likely
-- 'emitCond cond true_id' emits code to test whether the cond is true,
-- branching to true_id if so, and falling through otherwise.
-emitCond (BoolTest e) then_id = do
+emitCond (BoolTest e) then_id likely = do
else_id <- newBlockId
- emit (mkCbranch e then_id else_id Nothing)
+ emit (mkCbranch e then_id else_id likely)
emitLabel else_id
-emitCond (BoolNot (BoolTest (CmmMachOp op args))) then_id
+emitCond (BoolNot (BoolTest (CmmMachOp op args))) then_id likely
| Just op' <- maybeInvertComparison op
- = emitCond (BoolTest (CmmMachOp op' args)) then_id
-emitCond (BoolNot e) then_id = do
+ = emitCond (BoolTest (CmmMachOp op' args)) then_id (not <$> likely)
+emitCond (BoolNot e) then_id likely = do
else_id <- newBlockId
- emitCond e else_id
+ emitCond e else_id likely
emit (mkBranch then_id)
emitLabel else_id
-emitCond (e1 `BoolOr` e2) then_id = do
- emitCond e1 then_id
- emitCond e2 then_id
-emitCond (e1 `BoolAnd` e2) then_id = do
+emitCond (e1 `BoolOr` e2) then_id likely = do
+ emitCond e1 then_id likely
+ emitCond e2 then_id likely
+emitCond (e1 `BoolAnd` e2) then_id likely = do
-- we'd like to invert one of the conditionals here to avoid an
-- extra branch instruction, but we can't use maybeInvertComparison
-- here because we can't look too closely at the expression since
-- we're in a loop.
and_id <- newBlockId
else_id <- newBlockId
- emitCond e1 and_id
+ emitCond e1 and_id likely
emit (mkBranch else_id)
emitLabel and_id
- emitCond e2 then_id
+ emitCond e2 then_id likely
emitLabel else_id
-- -----------------------------------------------------------------------------