Parcourir la source

* always emit the procdef when calling a routine in llvm; this is
only required when calling a routine that returns a procvardef or
if it's a C-style varargs routine, but it's always allowed and
always doing it simplifies procvar handling

git-svn-id: trunk@32416 -

Jonas Maebe il y a 9 ans
Parent
commit
abd79d275f
3 fichiers modifiés avec 28 ajouts et 32 suppressions
  1. 16 8
      compiler/llvm/aasmllvm.pas
  2. 8 20
      compiler/llvm/hlcgllvm.pas
  3. 4 4
      compiler/llvm/llvmtype.pas

+ 16 - 8
compiler/llvm/aasmllvm.pas

@@ -510,10 +510,18 @@ uses
             end;
           la_invoke, la_call:
             begin
-              if opnr=1 then
-                result:=oper[2]^.def
-              else
-                internalerror(2013110102);
+              case opnr of
+                1: result:=oper[0]^.def;
+                3:
+                  begin
+                    if oper[3]^.typ=top_reg then
+                      result:=oper[2]^.def
+                    else
+                      internalerror(2015112001)
+                  end
+                else
+                  internalerror(2013110102);
+              end;
             end;
           la_br,
           la_unreachable:
@@ -963,9 +971,9 @@ uses
           have to insert a type conversion later from the alias def to the
           call def here; we can't always do that at the point the call itself
           is generated, because the alias declaration may occur anywhere }
-        loaddef(0,callpd);
+        loaddef(0,retsize);
         loadreg(1,dst);
-        loaddef(2,retsize);
+        loaddef(2,callpd);
         loadsymbol(3,name,0);
         loadparas(4,paras);
       end;
@@ -975,9 +983,9 @@ uses
       begin
         create_llvm(la_call);
         ops:=5;
-        loaddef(0,callpd);
+        loaddef(0,retsize);
         loadreg(1,dst);
-        loaddef(2,retsize);
+        loaddef(2,callpd);
         loadreg(3,reg);
         loadparas(4,paras);
       end;

+ 8 - 20
compiler/llvm/hlcgllvm.pas

@@ -51,7 +51,7 @@ uses
       procedure deallocallcpuregisters(list: TAsmList); override;
 
      protected
-      procedure a_call_common(list: TAsmList; pd: tabstractprocdef; const paras: array of pcgpara; const forceresdef: tdef; out res: tregister; out calldef: tdef; out hlretdef: tdef; out llvmretdef: tdef; out callparas: tfplist);
+      procedure a_call_common(list: TAsmList; pd: tabstractprocdef; const paras: array of pcgpara; const forceresdef: tdef; out res: tregister; out hlretdef: tdef; out llvmretdef: tdef; out callparas: tfplist);
      public
       function a_call_name(list : TAsmList;pd : tprocdef;const s : TSymStr; const paras: array of pcgpara; forceresdef: tdef; weak: boolean): tcgpara;override;
       function a_call_reg(list: TAsmList; pd: tabstractprocdef; reg: tregister; const paras: array of pcgpara): tcgpara; override;
@@ -336,7 +336,7 @@ implementation
     end;
 
 
-  procedure thlcgllvm.a_call_common(list: TAsmList; pd: tabstractprocdef; const paras: array of pcgpara; const forceresdef: tdef; out res: tregister; out calldef: tdef; out hlretdef: tdef; out llvmretdef: tdef; out callparas: tfplist);
+  procedure thlcgllvm.a_call_common(list: TAsmList; pd: tabstractprocdef; const paras: array of pcgpara; const forceresdef: tdef; out res: tregister; out hlretdef: tdef; out llvmretdef: tdef; out callparas: tfplist);
 
     procedure load_ref_anyreg(def: tdef; const ref: treference; reg: tregister; var callpara: pllvmcallpara);
       begin
@@ -432,16 +432,6 @@ implementation
     if (pd.typ=procvardef) and
        not pd.is_addressonly then
       pd:=tprocvardef(cprocvardef.getreusableprocaddr(pd));
-    { if the function returns a function pointer type or is varargs, we
-      must specify the full function signature, otherwise we can only
-      specify the return type }
-    if (po_varargs in pd.procoptions) or
-       ((pd.proccalloption in cdecl_pocalls) and
-        (pd.paras.count>0) and
-        is_array_of_const(tparavarsym(pd.paras[pd.paras.count-1]).vardef)) then
-      calldef:=get_call_pd(pd)
-    else
-      calldef:=llvmretdef;
   end;
 
 
@@ -449,12 +439,11 @@ implementation
     var
       callparas: tfplist;
       llvmretdef,
-      hlretdef,
-      calldef: tdef;
+      hlretdef: tdef;
       res: tregister;
     begin
-      a_call_common(list,pd,paras,forceresdef,res,calldef,hlretdef,llvmretdef,callparas);
-      list.concat(taillvm.call_size_name_paras(get_call_pd(pd),res,calldef,current_asmdata.RefAsmSymbol(pd.mangledname),callparas));
+      a_call_common(list,pd,paras,forceresdef,res,hlretdef,llvmretdef,callparas);
+      list.concat(taillvm.call_size_name_paras(get_call_pd(pd),res,llvmretdef,current_asmdata.RefAsmSymbol(pd.mangledname),callparas));
       result:=get_call_result_cgpara(pd,forceresdef);
       set_call_function_result(list,pd,llvmretdef,hlretdef,res,result);
     end;
@@ -464,12 +453,11 @@ implementation
     var
       callparas: tfplist;
       llvmretdef,
-      hlretdef,
-      calldef: tdef;
+      hlretdef: tdef;
       res: tregister;
     begin
-      a_call_common(list,pd,paras,nil,res,calldef,hlretdef,llvmretdef,callparas);
-      list.concat(taillvm.call_size_reg_paras(get_call_pd(pd),res,calldef,reg,callparas));
+      a_call_common(list,pd,paras,nil,res,hlretdef,llvmretdef,callparas);
+      list.concat(taillvm.call_size_reg_paras(get_call_pd(pd),res,llvmretdef,reg,callparas));
       result:=get_call_result_cgpara(pd,nil);
       set_call_function_result(list,pd,llvmretdef,hlretdef,res,result);
     end;

+ 4 - 4
compiler/llvm/llvmtype.pas

@@ -192,7 +192,7 @@ implementation
                   begin
                     if (opidx=3) and
                        (p.llvmopcode=la_call) then
-                      record_asmsym_def(p.oper[opidx]^.ref^.symbol,tpointerdef(p.oper[0]^.def).pointeddef,false)
+                      record_asmsym_def(p.oper[opidx]^.ref^.symbol,tpointerdef(p.oper[2]^.def).pointeddef,false)
                     { not a named register }
                     else if (p.oper[opidx]^.ref^.refaddr<>addr_full) then
                       record_asmsym_def(p.oper[opidx]^.ref^.symbol,p.spilling_get_reg_type(opidx),false);
@@ -277,11 +277,11 @@ implementation
           la_call:
             if p.oper[3]^.typ=top_ref then
               begin
-                maybe_insert_extern_sym_decl(toplevellist,p.oper[3]^.ref^.symbol,tpointerdef(p.oper[0]^.def).pointeddef);
+                maybe_insert_extern_sym_decl(toplevellist,p.oper[3]^.ref^.symbol,tpointerdef(p.oper[2]^.def).pointeddef);
                 symdef:=get_asmsym_def(p.oper[3]^.ref^.symbol);
                 { the type used in the call is different from the type used to
                   declare the symbol -> insert a typecast }
-                if not equal_llvm_defs(symdef,p.oper[0]^.def) then
+                if not equal_llvm_defs(symdef,p.oper[2]^.def) then
                   begin
                     if symdef.typ=procdef then
                       { ugly, but can't use getcopyas(procvardef) due to the
@@ -290,7 +290,7 @@ implementation
                         symtable) and "pointer to procedure" results in the
                         correct llvm type }
                       symdef:=cpointerdef.getreusable(tprocdef(symdef));
-                    cnv:=taillvm.op_reg_size_sym_size(la_bitcast,NR_NO,symdef,p.oper[3]^.ref^.symbol,p.oper[0]^.def);
+                    cnv:=taillvm.op_reg_size_sym_size(la_bitcast,NR_NO,symdef,p.oper[3]^.ref^.symbol,p.oper[2]^.def);
                     p.loadtai(3,cnv);
                   end;
               end;