@@ -117,11 +117,7 @@ gccFlags i = if i then ["-fwrapv"]
117 else ["-fwrapv", "-fno-strict-overflow"]
117 else ["-fwrapv", "-fno-strict-overflow"]
119gccDbg DEBUG = ["-g"]
119gccDbg DEBUG = ["-g"]
120−-- clang optimises sibling calls in O1, but gcc doesn't
120+gccDbg _ = []
121−-- on the other hand, O1 compiles significantly faster in clang without
122−-- any noticeable performance hit.
123−gccDbg TRACE = ["-O1", "-foptimize-sibling-calls"]
124−gccDbg _ = ["-O1", "-foptimize-sibling-calls"]
126cname :: Name -> String
122cname :: Name -> String
127cname n = "_idris_" ++ concatMap cchar (showCG n)
123cname n = "_idris_" ++ concatMap cchar (showCG n)
@@ -137,14 +133,14 @@ creg (T i) = "TOP(" ++ show i ++ ")"
137creg Tmp = "REG1"
133creg Tmp = "REG1"
139toDecl :: Name -> String
135toDecl :: Name -> String
140−toDecl f = "void " ++ cname f ++ "(VM*, VAL*);\n"
136+toDecl f = "void* " ++ cname f ++ "(VM*, VAL*);\n"
142toC :: Name -> [BC] -> String
138toC :: Name -> [BC] -> String
143toC f code
139toC f code
144 = -- "/* " ++ show code ++ "*/\n\n" ++
140 = -- "/* " ++ show code ++ "*/\n\n" ++
145− "void " ++ cname f ++ "(VM* vm, VAL* oldbase) {\n" ++
141+ "void* " ++ cname f ++ "(VM* vm, VAL* oldbase) {\n" ++
146− indent 1 ++ "INITFRAME;\n" ++
142+ indent 1 ++ "INITFRAME;\nloop:\n" ++
147− concatMap (bcc 1) code ++ "}\n\n"
143+ concatMap (bcc f 1) code ++ "}\n\n"
149showCStr :: String -> String
145showCStr :: String -> String
150showCStr s = '"' : foldr ((++) . showChar) "\"" s
146showCStr s = '"' : foldr ((++) . showChar) "\"" s
@@ -180,9 +176,9 @@ showCStr s = '"' : foldr ((++) . showChar) "\"" s
181 _ -> error $ "Can't happen: String of invalid length " ++ show s
177 _ -> error $ "Can't happen: String of invalid length " ++ show s
183−bcc :: Int -> BC -> String
179+bcc :: Name -> Int -> BC -> String
184−bcc i (ASSIGN l r) = indent i ++ creg l ++ " = " ++ creg r ++ ";\n"
180+bcc f i (ASSIGN l r) = indent i ++ creg l ++ " = " ++ creg r ++ ";\n"
185−bcc i (ASSIGNCONST l c)
181+bcc f i (ASSIGNCONST l c)
186 = indent i ++ creg l ++ " = " ++ mkConst c ++ ";\n"
182 = indent i ++ creg l ++ " = " ++ mkConst c ++ ";\n"
188 mkConst (I i) = "MKINT(" ++ show i ++ ")"
184 mkConst (I i) = "MKINT(" ++ show i ++ ")"
@@ -203,10 +199,10 @@ bcc i (ASSIGNCONST l c)
203 mkConst c | isTypeConst c = "MKINT(42424242)"
199 mkConst c | isTypeConst c = "MKINT(42424242)"
204 mkConst c = error $ "mkConst of (" ++ show c ++ ") not implemented"
200 mkConst c = error $ "mkConst of (" ++ show c ++ ") not implemented"
206−bcc i (UPDATE l r) = indent i ++ creg l ++ " = " ++ creg r ++ ";\n"
202+bcc f i (UPDATE l r) = indent i ++ creg l ++ " = " ++ creg r ++ ";\n"
207−bcc i (MKCON l loc tag []) | tag < 256
203+bcc f i (MKCON l loc tag []) | tag < 256
208 = indent i ++ creg l ++ " = NULL_CON(" ++ show tag ++ ");\n"
204 = indent i ++ creg l ++ " = NULL_CON(" ++ show tag ++ ");\n"
209−bcc i (MKCON l loc tag args)
205+bcc f i (MKCON l loc tag args)
210 = indent i ++ alloc loc tag ++
206 = indent i ++ alloc loc tag ++
211 indent i ++ setArgs 0 args ++ "\n" ++
207 indent i ++ setArgs 0 args ++ "\n" ++
212 indent i ++ creg l ++ " = " ++ creg Tmp ++ ";\n"
208 indent i ++ creg l ++ " = " ++ creg Tmp ++ ";\n"
@@ -220,21 +216,21 @@ bcc i (MKCON l loc tag args)
220 = "updateCon(" ++ creg Tmp ++ ", " ++ creg old ++ ", " ++ show tag ++ ", " ++
216 = "updateCon(" ++ creg Tmp ++ ", " ++ creg old ++ ", " ++ show tag ++ ", " ++
221 show (length args) ++ ");\n"
217 show (length args) ++ ");\n"
223−bcc i (PROJECT l loc a) = indent i ++ "PROJECT(vm, " ++ creg l ++ ", " ++ show loc ++
219+bcc f i (PROJECT l loc a) = indent i ++ "PROJECT(vm, " ++ creg l ++ ", " ++ show loc ++
224 ", " ++ show a ++ ");\n"
220 ", " ++ show a ++ ");\n"
225−bcc i (PROJECTINTO r t idx)
221+bcc f i (PROJECTINTO r t idx)
226 = indent i ++ creg r ++ " = GETARG(" ++ creg t ++ ", " ++ show idx ++ ");\n"
222 = indent i ++ creg r ++ " = GETARG(" ++ creg t ++ ", " ++ show idx ++ ");\n"
227−bcc i (CASE True r [(_, alt)] Nothing)
223+bcc f i (CASE True r [(_, alt)] Nothing)
228 = indent i ++ showCode i alt
224 = indent i ++ showCode i alt
230 showCode :: Int -> [BC] -> String
226 showCode :: Int -> [BC] -> String
231− showCode i bc = "{\n" ++ concatMap (bcc (i + 1)) bc ++
227+ showCode i bc = "{\n" ++ concatMap (bcc f (i + 1)) bc ++
232 indent i ++ "}\n"
228 indent i ++ "}\n"
233−bcc i (CASE True r code def)
229+bcc f i (CASE True r code def)
234 | length code < 6 && length code > 1 = showCase i def code
230 | length code < 6 && length code > 1 = showCase i def code
236 showCode :: Int -> [BC] -> String
232 showCode :: Int -> [BC] -> String
237− showCode i bc = "{\n" ++ concatMap (bcc (i + 1)) bc ++
233+ showCode i bc = "{\n" ++ concatMap (bcc f (i + 1)) bc ++
238 indent i ++ "}\n"
234 indent i ++ "}\n"
240 showCase :: Int -> Maybe [BC] -> [(Int, [BC])] -> String
236 showCase :: Int -> Maybe [BC] -> [(Int, [BC])] -> String
@@ -244,7 +240,7 @@ bcc i (CASE True r code def)
244 = indent i ++ "if (CTAG(" ++ creg r ++ ") == " ++ show t ++ ") " ++ showCode i c
240 = indent i ++ "if (CTAG(" ++ creg r ++ ") == " ++ show t ++ ") " ++ showCode i c
245 ++ indent i ++ "else\n" ++ showCase i def cs
241 ++ indent i ++ "else\n" ++ showCase i def cs
247−bcc i (CASE safe r code def)
243+bcc f i (CASE safe r code def)
248 = indent i ++ "switch(" ++ ctag safe ++ "(" ++ creg r ++ ")) {\n" ++
244 = indent i ++ "switch(" ++ ctag safe ++ "(" ++ creg r ++ ")) {\n" ++
249 concatMap (showCase i) code ++
245 concatMap (showCase i) code ++
250 showDef i def ++
246 showDef i def ++
@@ -254,11 +250,12 @@ bcc i (CASE safe r code def)
254 ctag False = "TAG"
250 ctag False = "TAG"
256 showCase i (t, bc) = indent i ++ "case " ++ show t ++ ":\n"
252 showCase i (t, bc) = indent i ++ "case " ++ show t ++ ":\n"
257− ++ concatMap (bcc (i+1)) bc ++ indent (i + 1) ++ "break;\n"
253+ ++ concatMap (bcc f (i+1)) bc ++ indent (i + 1) ++ "break;\n"
258− showDef i Nothing = ""
254+ showDef i Nothing = indent i ++ "default:\n" ++
255+ indent (i + 1) ++ "return NULL;\n"
259 showDef i (Just c) = indent i ++ "default:\n"
256 showDef i (Just c) = indent i ++ "default:\n"
260− ++ concatMap (bcc (i+1)) c ++ indent (i + 1) ++ "break;\n"
257+ ++ concatMap (bcc f (i+1)) c ++ indent (i + 1) ++ "break;\n"
261−bcc i (CONSTCASE r code def)
258+bcc f i (CONSTCASE r code def)
262 | intConsts code
259 | intConsts code
263-- = indent i ++ "switch(GETINT(" ++ creg r ++ ")) {\n" ++
260-- = indent i ++ "switch(GETINT(" ++ creg r ++ ")) {\n" ++
264-- concatMap (showCase i) code ++
261-- concatMap (showCase i) code ++
@@ -290,65 +287,67 @@ bcc i (CONSTCASE r code def)
291 strCase sv (s, bc) =
288 strCase sv (s, bc) =
292 indent i ++ "if (strcmp(" ++ sv ++ ", " ++ show s ++ ") == 0) {\n" ++
289 indent i ++ "if (strcmp(" ++ sv ++ ", " ++ show s ++ ") == 0) {\n" ++
293− concatMap (bcc (i+1)) bc ++ indent i ++ "} else\n"
290+ concatMap (bcc f (i+1)) bc ++ indent i ++ "} else\n"
294 biCase bv (BI b, bc) =
291 biCase bv (BI b, bc) =
295 indent i ++ "if (bigEqConst(" ++ bv ++ ", " ++ show b ++ ")) {\n"
292 indent i ++ "if (bigEqConst(" ++ bv ++ ", " ++ show b ++ ")) {\n"
296− ++ concatMap (bcc (i+1)) bc ++ indent i ++ "} else\n"
293+ ++ concatMap (bcc f (i+1)) bc ++ indent i ++ "} else\n"
297 iCase v (I b, bc) =
294 iCase v (I b, bc) =
298 indent i ++ "if (GETINT(" ++ v ++ ") == " ++ show b ++ ") {\n"
295 indent i ++ "if (GETINT(" ++ v ++ ") == " ++ show b ++ ") {\n"
299− ++ concatMap (bcc (i+1)) bc ++ indent i ++ "} else\n"
296+ ++ concatMap (bcc f (i+1)) bc ++ indent i ++ "} else\n"
300 iCase v (Ch b, bc) =
297 iCase v (Ch b, bc) =
301 indent i ++ "if (GETINT(" ++ v ++ ") == " ++ show (fromEnum b) ++ ") {\n"
298 indent i ++ "if (GETINT(" ++ v ++ ") == " ++ show (fromEnum b) ++ ") {\n"
302− ++ concatMap (bcc (i+1)) bc ++ indent i ++ "} else\n"
299+ ++ concatMap (bcc f (i+1)) bc ++ indent i ++ "} else\n"
303 iCase v (B8 w, bc) =
300 iCase v (B8 w, bc) =
304 indent i ++ "if (GETBITS8(" ++ v ++ ") == " ++ show (fromEnum w) ++ ") {\n"
301 indent i ++ "if (GETBITS8(" ++ v ++ ") == " ++ show (fromEnum w) ++ ") {\n"
305− ++ concatMap (bcc (i+1)) bc ++ indent i ++ "} else\n"
302+ ++ concatMap (bcc f (i+1)) bc ++ indent i ++ "} else\n"
306 iCase v (B16 w, bc) =
303 iCase v (B16 w, bc) =
307 indent i ++ "if (GETBITS16(" ++ v ++ ") == " ++ show (fromEnum w) ++ ") {\n"
304 indent i ++ "if (GETBITS16(" ++ v ++ ") == " ++ show (fromEnum w) ++ ") {\n"
308− ++ concatMap (bcc (i+1)) bc ++ indent i ++ "} else\n"
305+ ++ concatMap (bcc f (i+1)) bc ++ indent i ++ "} else\n"
309 iCase v (B32 w, bc) =
306 iCase v (B32 w, bc) =
310 indent i ++ "if (GETBITS32(" ++ v ++ ") == " ++ show (fromEnum w) ++ ") {\n"
307 indent i ++ "if (GETBITS32(" ++ v ++ ") == " ++ show (fromEnum w) ++ ") {\n"
311− ++ concatMap (bcc (i+1)) bc ++ indent i ++ "} else\n"
308+ ++ concatMap (bcc f (i+1)) bc ++ indent i ++ "} else\n"
312 iCase v (B64 w, bc) =
309 iCase v (B64 w, bc) =
313 indent i ++ "if (GETBITS64(" ++ v ++ ") == " ++ show (fromEnum w) ++ ") {\n"
310 indent i ++ "if (GETBITS64(" ++ v ++ ") == " ++ show (fromEnum w) ++ ") {\n"
314− ++ concatMap (bcc (i+1)) bc ++ indent i ++ "} else\n"
311+ ++ concatMap (bcc f (i+1)) bc ++ indent i ++ "} else\n"
315 showDefS i Nothing = ""
312 showDefS i Nothing = ""
316− showDefS i (Just c) = concatMap (bcc (i+1)) c
313+ showDefS i (Just c) = concatMap (bcc f (i+1)) c
318−bcc i (CALL n) = indent i ++ "CALL(" ++ cname n ++ ");\n"
315+bcc f i (CALL n) = indent i ++ "CALL(" ++ cname n ++ ");\n"
319−bcc i (TAILCALL n) = indent i ++ "TAILCALL(" ++ cname n ++ ");\n"
316+bcc f i (TAILCALL n)
317+ | f == n = indent i ++ "goto loop;\n"
318+ | otherwise = indent i ++ "TAILCALL(" ++ cname n ++ ");\n"
320−bcc i (SLIDE n) = indent i ++ "SLIDE(vm, " ++ show n ++ ");\n"
319+bcc f i (SLIDE n) = indent i ++ "SLIDE(vm, " ++ show n ++ ");\n"
321−bcc i REBASE = indent i ++ "REBASE;\n"
320+bcc f i REBASE = indent i ++ "REBASE;\n"
322−bcc i (RESERVE 0) = ""
321+bcc f i (RESERVE 0) = ""
323−bcc i (RESERVE n) = indent i ++ "RESERVE(" ++ show n ++ ");\n"
322+bcc f i (RESERVE n) = indent i ++ "RESERVE(" ++ show n ++ ");\n"
324−bcc i (ADDTOP 0) = ""
323+bcc f i (ADDTOP 0) = ""
325−bcc i (ADDTOP n) = indent i ++ "ADDTOP(" ++ show n ++ ");\n"
324+bcc f i (ADDTOP n) = indent i ++ "ADDTOP(" ++ show n ++ ");\n"
326−bcc i (TOPBASE n) = indent i ++ "TOPBASE(" ++ show n ++ ");\n"
325+bcc f i (TOPBASE n) = indent i ++ "TOPBASE(" ++ show n ++ ");\n"
327−bcc i (BASETOP n) = indent i ++ "BASETOP(" ++ show n ++ ");\n"
326+bcc f i (BASETOP n) = indent i ++ "BASETOP(" ++ show n ++ ");\n"
328−bcc i STOREOLD = indent i ++ "STOREOLD;\n"
327+bcc f i STOREOLD = indent i ++ "STOREOLD;\n"
329−bcc i (OP l fn args) = indent i ++ doOp (creg l ++ " = ") fn args ++ ";\n"
328+bcc f i (OP l fn args) = indent i ++ doOp (creg l ++ " = ") fn args ++ ";\n"
330−bcc i (FOREIGNCALL l rty (FStr ('#':name)) [])
329+bcc f i (FOREIGNCALL l rty (FStr ('#':name)) [])
331 = indent i ++
330 = indent i ++
332 c_irts (toFType rty) (creg l ++ " = ") name ++ ";\n"
331 c_irts (toFType rty) (creg l ++ " = ") name ++ ";\n"
333−bcc i (FOREIGNCALL l rty (FStr fn@('&':name)) [])
332+bcc f i (FOREIGNCALL l rty (FStr fn@('&':name)) [])
334 = indent i ++
333 = indent i ++
335 c_irts (toFType rty) (creg l ++ " = ") fn ++ ";\n"
334 c_irts (toFType rty) (creg l ++ " = ") fn ++ ";\n"
336−bcc i (FOREIGNCALL l rty (FStr fn) (x:xs)) | fn == "%wrapper"
335+bcc f i (FOREIGNCALL l rty (FStr fn) (x:xs)) | fn == "%wrapper"
337 = indent i ++
336 = indent i ++
338 c_irts (toFType rty) (creg l ++ " = ")
337 c_irts (toFType rty) (creg l ++ " = ")
339 ("_idris_get_wrapper(" ++ creg (snd x) ++ ")") ++ ";\n"
338 ("_idris_get_wrapper(" ++ creg (snd x) ++ ")") ++ ";\n"
340−bcc i (FOREIGNCALL l rty (FStr fn) (x:xs)) | fn == "%dynamic"
339+bcc f i (FOREIGNCALL l rty (FStr fn) (x:xs)) | fn == "%dynamic"
341 = indent i ++ c_irts (toFType rty) (creg l ++ " = ")
340 = indent i ++ c_irts (toFType rty) (creg l ++ " = ")
342 ("(*(" ++ cFnSig "" rty xs ++ ") GETPTR(" ++ creg (snd x) ++ "))" ++
341 ("(*(" ++ cFnSig "" rty xs ++ ") GETPTR(" ++ creg (snd x) ++ "))" ++
343 "(" ++ showSep "," (map fcall xs) ++ ")") ++ ";\n"
342 "(" ++ showSep "," (map fcall xs) ++ ")") ++ ";\n"
344−bcc i (FOREIGNCALL l rty (FStr fn) args)
343+bcc f i (FOREIGNCALL l rty (FStr fn) args)
345 = indent i ++
344 = indent i ++
346 c_irts (toFType rty) (creg l ++ " = ")
345 c_irts (toFType rty) (creg l ++ " = ")
347 (fn ++ "(" ++ showSep "," (map fcall args) ++ ")") ++ ";\n"
346 (fn ++ "(" ++ showSep "," (map fcall args) ++ ")") ++ ";\n"
348−bcc i (FOREIGNCALL l rty _ args) = error "Foreign Function calls cannot be partially applied, without being inlined."
347+bcc f i (FOREIGNCALL l rty _ args) = error "Foreign Function calls cannot be partially applied, without being inlined."
349−bcc i (NULL r) = indent i ++ creg r ++ " = NULL;\n" -- clear, so it'll be GCed
348+bcc f i (NULL r) = indent i ++ creg r ++ " = NULL;\n" -- clear, so it'll be GCed
350−bcc i (ERROR str) = indent i ++ "fprintf(stderr, " ++ show str ++ "); fprintf(stderr, \"\\n\"); exit(-1);\n"
349+bcc f i (ERROR str) = indent i ++ "fprintf(stderr, " ++ show str ++ "); fprintf(stderr, \"\\n\"); exit(-1);\n"
351−-- bcc i c = error (show c) -- indent i ++ "// not done yet\n"
350+-- bcc f i c = error (show c) -- indent i ++ "// not done yet\n"
353fcall (t, arg) = irts_c (toFType t) (creg arg)
352fcall (t, arg) = irts_c (toFType t) (creg arg)
354-- Deconstruct the Foreign type in the defunctionalised expression and build
353-- Deconstruct the Foreign type in the defunctionalised expression and build