Re: [fpc-devel] x86_64 Optimizer Overhaul
> On Dec 12, 2018, at 7:20 PM, Martok wrote: > > Checking out the memory manager(s) could be useful as well - there are a lot > of > small allocations, that generally tends to put much stress on it. > And any improvement there would also directly benefit user applications. I was going to say the same thing myself and even planned to do a test. My profiles show the top hits being getmem/freemem which really don’t need to be there. There’s no reason to be allocating and freeing nodes (for example) over and over again when we could just allocate a large pool at startup and return to the pool instead of freeing. It would make the compiler utilize more memory but that’s a good trade off for me personally. This is especially a good idea because the compiler is a one pass program so leaks over the long term aren’t a problem. Regards, Ryan Joseph ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] x86_64 Optimizer Overhaul
I’ve spent some time in the compiler sources now and I’m curious just where people think the bottle necks for performance actually are. It’s such a complicated system for anyone one person to have a good understanding of so it’s not clear where to begin looking. > On Dec 12, 2018, at 9:42 AM, J. Gareth Moreton > wrote: > > The overhaul primarily increases the speed of compilation, but it makes some > minor improvements to conditional branches here and there. Nevertheless, I'm > always happy to find a saving here and there in the compiled assembly > language! Regards, Ryan Joseph ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] x86_64 Optimizer Overhaul
> On Dec 9, 2018, at 9:15 AM, J. Gareth Moreton > wrote: > > Hmmm, that's a shame if the time difference is so small. Up to you if it's > worth it or not. I hoped it would be slightly better than that, although if > it's consistently faster, especially with large projects, then it's a winner > in my eyes. Fingers crossed! My biggest project is only ~20 seconds so it’s just not a big enough code base I think. How do we even know how much of the time was spent on code generation vs parsing? All I looked at was the final time using -vs when it got to the linking phase. Regards, Ryan Joseph ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] x86_64 Optimizer Overhaul
got it compiling but I need a better way to specify the changed rtl/package units. I just did a “make clean all” but I need to specify the new location of the rtf/packages units which are no longer in the default locations. Is there a better way than adding tons of -Fu’s in the command line? Regards, Ryan Joseph ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] x86_64 Optimizer Overhaul
> On Dec 9, 2018, at 9:02 AM, J. Gareth Moreton > wrote: > > (This should probably be on the mailing list because it's helpful to everyone) > > Hmmm, I'm not sure about that one - those shouldn't be affected. Just the > standard "make clean all" should work. > > However, the document here contains everything about building FPC: > http://www.stack.nl/~marcov/buildfaq.pdf - not sure why your packages aren't > in the default directories now though... the patches only change a few source > files. > > Gareth aka. Kit The reason is that PPU versions changed so I can’t use the units at the default system locations. Not sure how the compiler decides but it was looking for units at the 3.1.1 install location which is an older PPU version. There should be a single command to specify a top-level directory that wins out over default locations. Regards, Ryan Joseph ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] x86_64 Optimizer Overhaul
Got everything building finally but the time difference is so small I'll need to make a script to compile multiple times and average all the runs. Is it even worth the time doing that? Regards, Ryan Joseph ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] x86_64 Optimizer Overhaul
Couldn’t figure out the patching. I tried a dry run but it doesn’t seem to find the file. Downloaded from svn cd trunk patch < /Users/ryanjoseph/Downloads/overhaul-64-32-split.patch --dry-run (Stripping trailing CRs from patch.) can't find file to patch at input line 5 Perhaps you should have used the -p or --strip option? The text leading up to this was: -- |Index: compiler/x86/aoptx86.pas |=== |--- compiler/x86/aoptx86.pas (revision 40472) |+++ compiler/x86/aoptx86.pas (working copy) -- File to patch: > On Dec 9, 2018, at 7:11 AM, J. Gareth Moreton > wrote: > > Had any luck with this? Regards, Ryan Joseph ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] x86_64 Optimizer Overhaul
I was stupid and didn’t use the right options. They work now except this one: sudo patch -p0 < /Users/ryanjoseph/Downloads/overhaul-base.patch (Stripping trailing CRs from patch.) patching file compiler/aopt.pas patch: malformed patch at line 15: Index: compiler/aoptbase.pas did it fail? > On Dec 9, 2018, at 8:36 AM, Ryan Joseph wrote: > > Couldn’t figure out the patching. I tried a dry run but it doesn’t seem to > find the file. Regards, Ryan Joseph ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] x86_64 Optimizer Overhaul
> On Dec 7, 2018, at 5:11 AM, J. Gareth Moreton > wrote: > > Does anyone have other test projects to compile that would give more coverage > for the timing metrics? Sure. How do I download and build? Are you just relying the FPC standard output for timing or are there are special switches to show compiles times more accurate? Regards, Ryan Joseph ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] LLVM code generator
> On Dec 2, 2018, at 5:26 PM, Jonas Maebe wrote: > > > The LLVM code generator is more or less ready, including Dwarf-EH-based > exception handling support. It's currently only supported on Darwin/x86-64 > and Linux/x86-64, but it can do a "make all" and the testsuite can be > finished as well. There are still some extra failures that do not happen with > the built-in code generator, but most tests work fine. What does this mean for end users? Do we get better debugging support in LLDB? Regards, Ryan Joseph ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] Type range in generic
> On Dec 3, 2018, at 6:33 AM, Simon Jackson wrote: > > Just an idea. > > Class variables. If generics are used, then the same code can be used for > differing pointer types. (Classes) as long as a specifier on the "generic > class variable" and no generic specialize or <> is in the > > class generic x: TObject; > > Can it be shared across all generics of a kind? > > The code density in the cache would be good for all common generics. I don’t get what this is trying to accomplish or how it’s used. Example? Regards, Ryan Joseph ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] Type range in generic
> On Dec 2, 2018, at 4:00 PM, Sven Barth via fpc-devel > wrote: > > Please report as a bug. I don’t get a bug on this in the trunk version I’m using. Maybe it was fixed? Regards, Ryan Joseph ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] Default properties
> On Sep 10, 2018, at 4:23 PM, Ryan Joseph wrote: > > I think I can use tcallcandidates.create_operator to test this but what do I > pass for the call param node? I didn’t get an answer on this but I was able to figure it out for myself, albeit only for arithmetic operators, i.e. class operator + (left: TWrapper; right: integer): TWrapper; ppn:=ccallparanode.create(right.getcopy,ccallparanode.create(left.getcopy,nil)); ppn.get_paratype; candidates:=tcallcandidates.create_operator(optoken,ppn); if candidates.count > 0 then begin candidates.get_information; result := candidates.choose_best(tabstractprocdef(operpd),false) > 0; end; For assignment operators like: class operator := (right: integer): TWrapper; the code doesn’t return any candidates. I think this is because the tcallparanode is wrong but I don’t know what to provide. Any ideas? Regards, Ryan Joseph ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] Default properties
One more question. With the syntax: wrapper + 1 I get to the point where I have 2 nodes parsed. p2 is an ordconst node (the value “1") and p1 is a load node (wrapper, which is a record). I need to check the resultdef for p1 to see if the + operator is overloaded so I can determine if the base record or the default property takes precedence. I think I can use tcallcandidates.create_operator to test this but what do I pass for the call param node? from pexpr.pas: p2:=sub_expr(succ(pred_level),flags+[ef_accept_equal],nil); case oldt of _PLUS : p1:=caddnode.create(addn,p1,p2); _MINUS : p1:=caddnode.create(subn,p1,p2); _STAR : p1:=caddnode.create(muln,p1,p2); _SLASH : p1:=caddnode.create(slashn,p1,p2); _EQ: p1:=caddnode.create(equaln,p1,p2); _GT : p1:=caddnode.create(gtn,p1,p2); Regards, Ryan Joseph ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] Default properties
> On Sep 7, 2018, at 6:27 PM, Sven Barth via fpc-devel > wrote: > > tcallcandidates in htypechk.pas is your friend. That is the *only* class that > deals with overload resolution and collects the eligible overloads from > various sources (e.g. loaded units, current type, helper types). Essentially > you only need to search for a procsym with the name of method inside the > default field (all proceeds with the same name share the same procsym) and > pass that on, the remainder of tcallcandidates will deal with overload > resolution (you only need to make sure that the correct "Self", namely the > default field is picked for that). > Thanks, I got this working. Just a general question. Can you clarify the difference between “tloadnode”, “tsubscriptnode” and “tcallnode”? I want to make sure I’m using them correctly. I ask because I’m trying to parse: wrapper + 1 { wrapper being a record with a default property } “wrapper” is being parsed as a load node but I want to convert it to “wrapper.helper” by appending the default property. I found I can make a new subscript node using the existing load node but is that the preferred method? p1:=csubscriptnode.create(default_property,p1); { p1 being the load node for “wrapper” } Regards, Ryan Joseph ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
[fpc-devel] Default properties
I’m moving my technical questions about default properties here so I don’t clutter up the other list. I’m still new to the compiler please bear with me. The first problem I’m having is how to resolve duplicate functions with overloads. For example in TWrapper there’s multiple overloads for DoThis and we need to determine if TWrapper.DoThis should use TWrapper or the THelperA from the default property. type THelperA = record procedure DoThis; end; type TWrapper = record objA: THelperA; property helperA: THelperA read objA write objA; default; procedure DoThis(param: integer); overload; procedure DoThis(param: string); overload; end; var wrapper: TWrapper; begin wrapper.DoThis(1); // DoThis is from TWrapper but how can we determine this? What I’m narrowing in on is: in pexpr.pas do_member_read() takes the load node and converts it to a call node and this is where I need to determine what definition the function belongs to. So in the example above we get “DoThis” how can we determine if TWrapper or THelperA has a matching function with matching parameters? searchsym_in_record usually returns the correct definition but I need to scan 2 possible definitions instead of just the first one specified in the load node. do_proc_call() parses parameters into a tcallparanode which is good. do_typecheckpass on the tcallnode from do_proc_call() will find procsym candidates in the record def which the node was created with. I would use this to query but it forces a syntax error which isn’t what I want. Hopefully that makes sense. So my question is, is there an existing way to search a tabstractrecorddef given a name and parameter list and return a found or not found answer? I could start pulling stuff out of do_typecheckpass() but I suspect there’s already a way to do this. Regards, Ryan Joseph ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] Adding procedures using nodes
> On Aug 2, 2018, at 2:41 PM, Ryan Joseph wrote: > > So the way FreeInstance is called by adding it within a destructor isn’t > exactly what I needed because it requires a destructor actually be present in > the class. > > The next thing I’d like to try is adding a procedure dynamically using nodes. > I’ve seen how if statements are made doing things like: Once again I think this is not useful so it can be disregarded. I wanted to learn how I could call Free on class fields (like management operators call Finalize on records) but it’s more complicated than I thought (again). Records with management operators hook into the RTTI system it looks like, but how does a record with management operators get added to the classes RTTI information? I mean in TObject.CleanupInstance there is a vInitTable which gets set if the record has management operators in them but I can’t find where. Regards, Ryan Joseph ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
[fpc-devel] Adding procedures using nodes
So the way FreeInstance is called by adding it within a destructor isn’t exactly what I needed because it requires a destructor actually be present in the class. The next thing I’d like to try is adding a procedure dynamically using nodes. I’ve seen how if statements are made doing things like: addstatement(newstatement,cifnode.create( caddnode.create(andn, caddnode.create(unequaln, load_self_pointer_node, cnilnode.create), caddnode.create(unequaln, ctypeconvnode.create( load_vmt_pointer_node, voidpointertype), cpointerconstnode.create(0,voidpointertype))), ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node,[],nil), nil)); but are there any examples of creating a procedural with nodes someone could point me to? I’d like to do something like: procedure DoSomething(param); begin end; so I could call the procedure with a parameter and have a block node (I think begin/end is a block node) so I could add some statements inside that. I’m having fun learning how the compiler works but it’s pretty complicated without any guidance. Thanks. Regards, Ryan Joseph ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] FreeInstance
> On Aug 1, 2018, at 3:28 PM, Sven Barth via fpc-devel > wrote: > > If you'd look at the code you quoted you'd see that this is only inserted > *inside* a destructor (the check for potype_destructor; current_procinfo is > the currently compiled routine). So, no, your code is not enough. You need to > declare a class with a destructor, then the code would be entered. > Now I see what’s happening! I would have caught this before but I had the class in another unit so it was compiled before I ran the debugger and I never got inside the destructor. Thanks guys. Regards, Ryan Joseph ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] FreeInstance
> On Aug 1, 2018, at 9:17 AM, Sven Barth via fpc-devel > wrote: > > Search the compiler's source for the string 'FREEINSTANCE'; you'll find two > locations, one in ngenutil and one in psub. The latter is the one you want. > Yeah, this is the first place I looked but current_structdef is always nil so it never progresses past that point. Is this test program not enough to get FreeInstance called? program test; var obj1: TObject; begin obj1 := TObject.Create; obj1.Free; end. === function generate_bodyexit_block:tnode; var srsym : tsym; para : tcallparanode; newstatement : tstatementnode; oldlocalswitches: tlocalswitches; begin result:=internalstatements(newstatement); if assigned(current_structdef) then begin { Don't test self and the vmt here. The reason is that } { a constructor already checks whether these are valid } { before. Further, in case of TThread the thread may} { free the class instance right after AfterConstruction } { has been called, so it may no longer be valid (JM)} oldlocalswitches:=current_settings.localswitches; current_settings.localswitches:=oldlocalswitches-[cs_check_object,cs_check_range]; { a destructor needs a help procedure } if (current_procinfo.procdef.proctypeoption=potype_destructor) then begin if is_class(current_structdef) then begin srsym:=search_struct_member(current_structdef,'FREEINSTANCE'); Regards, Ryan Joseph ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] FreeInstance
> On Jul 31, 2018, at 9:56 AM, Ryan Joseph wrote: > > then how does it get invoked then? there must be some node added somewhere > but I can’t find it. I’m still trying to find this with no luck. I suspect there’s a call node added when the compiler detects a destructor was called (maybe in ncal.pas or similar node unit) but I have no idea where. Any ideas? Regards, Ryan Joseph ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] FreeInstance
> On Jul 31, 2018, at 9:48 AM, Thorsten Engler wrote: > > I don't think it's called anywhere in the source. It's called by the compiler > after the destructor has finished. The same way that InitInstance is run > before the constructor is called. then how does it get invoked then? there must be some node added somewhere but I can’t find it. Regards, Ryan Joseph ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
[fpc-devel] FreeInstance
Looking at the FPC source now and it appears FreeInstance is a hidden method which is not called from the TObject destructor. Where/how is this method called in the source? I’ve been in the debugger for over an hour and I still can’t find it. Regards, Ryan Joseph ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] Progress of pure function research
> On Jul 15, 2018, at 11:01 PM, J. Gareth Moreton > wrote: > > So far I'm mostly researching how the node builder works, specifically how > inline > functions are handled, since that's a situation where a 'call' node is > effectively replaced, and I intend to builda similar system to handle pure > functions. I’ve looked at the FPC sources recently but I still don’t understand the basics. I see lots of TDef,TSym,TSymTable classes. What are those used for? You mentioned nodes and I wonder if that’s what those are. Regards, Ryan Joseph ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] Pure function Wiki page
> On Jul 9, 2018, at 3:25 AM, Sven Barth via fpc-devel > wrote: > > It would allow you to declare constants that use those functions with the > compiler evaluating them at compile time. That’s a double win then. Very good idea this is. Regards, Ryan Joseph ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
[fpc-devel] Default record fields
I posted this on the main list before but I want to repost here. Last month I decided finally after years to try working on the compiler and in short time I was able to add parameters to macros (like in C). The FPC list appeared to universally despise this idea so I guess I’ll just sit on it and take it as a learning experience if nothing else. The next idea I had was to add default values to record fields (like I use in C++, C#, Swift etc…) but I got some upset tones from people on this also, albeit not so bad. Anyways I decided (as a learning experience) I would try to implement this also but it’s probably too complicated to figure out on my own and without understanding even the basics of the how the compiler works. I chose this one area because it’s a problem I personally have with FPC and miss from C++ and I thought that it might be doable for a beginner. I was able to parse out default values in fields but 1) I’m not sure what exactly a “value” *is* in terms of the compiler and 2) I don’t understand how variables are assigned those values. There’s lots of TDef/TSym etc.. and it’s difficult to understand what they’re used for. If I post some more specifics is anyone interested in helping me do this or answering basic questions on the compiler architecture? Regards, Ryan Joseph ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] Pure function Wiki page
> On Jul 8, 2018, at 10:55 AM, Marco van de Voort wrote: > > It doesn't explain why you chose for a modifier rather than preprocessor > switch. Performance aside I think it’s useful to mark a function as “pure” so you can guarantee it’s not messing with global state. I’m sure I could have used that at some point over the years. Regards, Ryan Joseph ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] Pure function Wiki page
> On Jul 8, 2018, at 8:50 AM, J. Gareth Moreton > wrote: > > With some blessing from Florian on the concept, I've set up a Wiki page > discussing the design proposals for the support of pure functions, as well as > some explanation on what they actually are. > What are the performance benefits? It sounds like this is a proposal for a compiler optimization which we can explicitly opt in to, but what exactly is the optimization? If nothing else I like the idea as a way to enforce a function is not accessing global state. Kind of like const for functions. Regards, Ryan Joseph ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel