[LLVMdev] Reviewer for our Path Profiling Implementation

Adam Preuss apreuss at ualberta.ca
Wed Dec 8 11:30:50 PST 2010


Thank you for your suggestions on the patch. If the patch is committed, I would be willing to maintain it, though
I am not sure what is all involved or how I am made aware of changes that need to be made.

The technical report https://www.cs.ualberta.ca/system/files/tech_report/2010/PreussPathProfLLVM.pdf contains
my benchmarks relating to profiling overhead in LLVM.

Over the next week I will work through the patch and make the appropriate adjustments. I have some responses to your
comments below as well. Things that I haven't commented on make sense and I will change them.

Adam

On 2010-12-07, at 5:09 PM, Andrew Trick wrote:

> On Dec 3, 2010, at 11:21 AM, Adam Preuss wrote:
>> I am a student at the University of Alberta under the  
>> supervision of José Nelson Amaral, and I have been working on  
>> implementing path profiling into LLVM. I have completed my project
>> and would like to submit it.
>> 
>> We are looking for a reviewer for the path profiling implementation. We
>> have sent previous requests to the llvmdev list but have so far been
>> unsuccessful.
>> 
>> Please see the attached patch and associated documentation.
>> 
>> Adam Preuss
>> 
>> <path-profiling.patch>
>> <doc.pdf>
> 
> Hi Adam,
> 
> Thanks for making the effort to contribute. I have seen some valid
> feedback to the effect that we can't keep something in mainline unless
> is it actively used or maintained. However, I'm willing to give you a
> review so it can be checked in, with no guarantee that the code won't
> be removed if it breaks, or replaced by a different profiler if we
> ever adopt one for active use.
> 
> Thanks for the design doc. We'll be sure to get that checked into
> llvm.org/pubs. A couple of design questions: Can you compare the
> overhead of LLVM's edge profiler vs path profiler, both run time
> (profile time) and compile time? How do you anticipate the path
> profile to be used by the optimizer?
> 
> Regarding the implementation, a couple of style problems should be addressed:
> 
> - Tabs absolutely need to be removed:
> http://llvm.org/docs/CodingStandards.html#scf_spacestabs
> 
> - I see a few violation of 80 cols. Not many, but too many for me
>  to list here.
> 
> If you think any of my specific suggestions below are off-base, don't
> follow them, just respond with some justification. Since you've
> already done rigorous verification, and I'm not overly concerned with
> optimality, most of my comments are style related.
> 
> ---
> +static cl::opt<std::string>
> +EdgeProfileFilename("path-profile-verifier-file",
> +	cl::init("edgefrompath.llvmprof.out"),
> +	cl::value_desc("filename"),
> +  cl::desc("Edge profile file generated by -path-profile-verifier"));
> ...
> +// command line option for loading path profiles
> +static cl::opt<std::string>
> +PathProfileInfoFilename("path-profile-loader-file", cl::init("llvmprof.out"),
> +                        cl::value_desc("filename"),
> +                        cl::desc("Path profile file loaded by -path-profile-loader"));
> ...
> +// Are we enabling early termination
> +static cl::opt<bool> ProcessEarlyTermination("process-early-termination",
> +	cl::desc("In path profiling, insert extra instrumentation to account for "
> +           "unexpected function termination."));
> ...
> +// Should we print the dot-graphs
> +static cl::opt<bool> DotPathDag("dot-pathdag",
> +	cl::desc("Output the path profiling DAG for each function."));
> 
> Please add cl::Hidden to all new flags, and give them all
> a "path-profile" prefix so they aren't scattered in the hidden help text.

> 
> +++ include/llvm/Analysis/ProfileInfoTypes.h
> 
> +#define PP_ARRAY 0
> +#define PP_HASH  1
> 
> Why not an enum?
> 
> +typedef struct {
> +  unsigned fnNumber; /* function number for these counters */
> +  unsigned numEntries;   /* number of entries stored */
> +} PathHeader;
> +
> +typedef struct {
> +  unsigned pathNumber;
> +  unsigned pathCounter;
> +} PathTableEntry;
> 
> Being global types, they need a PathProfiling-specific name or prefix
> (there are other kinds of paths). To be proper, should they also be under:
> #if defined(__cplusplus)
> extern "C" {
> endif
> 
> You may even want to remove the emacs hint "-*- C++ -*-" from both
> this header and Profiling.h
> 

> +++ runtime/libprofile/Profiling.h
> 
> +#include <stdint.h>
> +#include <unistd.h>
> 
> Include these only in the .cpp files in which they're needed. Include
> them after any non-system headers.
> 
> +typedef int PType; /* type for storing enum ProfilingType on disk */
> 
> I realize PType is currently only included within libprofile, but the
> general guideline is to make type names in the global namespace
> descriptive. Such as ProfileInfoStorageType.
> 
> I'm not sure why you made it a global type. Was it for use by the
> profile loader? If so, I think it would need to be in
> ProfileInfoTypes.h under extern "C".
> 
> +++ runtime/libprofile/CommonProfiling.c
> 
> +static int OutFile = -1;
> 
> I'm not sure why OutFile cannot remain a local static within
> getOutFile.
> 
> +  int res;
> ...
> +  res = write(outFile, &PTy, sizeof( Profile));
> 
> Some builds may warn of the unused result. If you're not checking the
> result, you probably shouldn't retrieve it.
> 
> +++ runtime/libprofile/PathProfiling.c
> 
> + inline uint32_t* getPathCounter(uint32_t functionNumber, uint32_t pathNumber) {
> ...
> +	if( ((ftEntry_t*)ft)[functionNumber-1].array == 0)
> +		((ftEntry_t*)ft)[functionNumber-1].array =
> calloc(sizeof(pathHashTable_t), 1);
> 
> It's not immediately obvious to me why you always cast "ft".

I think there used to be a reason, but I don't see a reason to any more.

> 
> Since this is a runtime lib, it may be wise to add array bounds checks.

I can, but a path number will never be larger than the array size so I don't think it's necessary.

> 
> In getPathCounter can you check that type == PP_HASH and size == 0
> before writing to the data structure?
> 
> +++ lib/Transforms/Instrumentation/ProfilingUtils.h	(working copy)
> 
> +#include "llvm/DerivedTypes.h"
> 
> Add the include only in the .cpp files that need it.
> 
> +++ include/llvm/Analysis/PathNumbering.h
> 
> +namespace llvm {
> +	class BallLarusNode;
> 
> I don't think you should indent large namespaces bodies. Same goes for
> the rest of the files.
> 
> +++ lib/Analysis/PathNumbering.cpp
> 
> The constructor and accessors are trivial and can be defined inline.
> 
> + void BallLarusDag::calculatePathNumbersFrom(BallLarusNode* node) {
> ...
> +      BallLarusEdge* currEdge = *succ;
> +      currEdge->setWeight(sumPaths);
> +      succNode = currEdge->getTarget();
> +      unsigned succPaths = succNode->getNumberPaths();
> +      isReady = isReady && (succPaths != 0);
> 
> If a successor is not finished, can you early return here instead of
> prematurely setting the edge weights? Better yet, keep a count
> of the remaining successors, then only call calculatePathNumberFrom()
> once per node after all successors are visited? You already visiting
> each pred edge after finishing a node, just decrement its remaining
> count at that time.

Yes, I don't see why not.

> 
> +++ lib/Transforms/Instrumentation/PathProfiling.cpp
> 
> + void PathProfiler::insertInstrumentationStartingAt(BLInstrumentationEdge*
> 
> Does this need to be recursive? If you simply visit the edges in dfs
> order (creation order?) would that be sufficient? I don't think you
> even need to create RPO order, since phis can be lazily prepared.

I think it has to traverse in the current method, otherwise certain pointers to
path counters, phi nodes, etc will not be initialized properly in my representation 
of the graph. I will it over more closely though.

> 
> +++ include/llvm/Analysis/PathProfileInfo.h
> 
> + #ifndef LLVM_ANALYSIS_BALLLARUSPATHPROFILEINFO_H
> 
> Symbol doesn't really need to be this long.
> 
> +#include <stack>
> +#include "llvm/BasicBlock.h"
> +#include "llvm/Analysis/PathNumbering.h"
> 
> Put system headers after user headers.
> 
> +namespace llvm {
> +	class Path;
> 
> A class Path already exists. You just got lucky it's in llvm::sys. Please
> wrap your classes in a namespace (e.g. llvm::PathProfile) or give
> them fully descriptive names.
> 
> +++ include/llvm/Analysis/PathProfileInfo.cpp
> 
> +unsigned PathEdge::getDuplicateNumber() {
> +	return _duplicateNumber;
> +}
> +
> +BasicBlock* PathEdge::getSource() {
> +	return _source;
> +}
> +
> +BasicBlock* PathEdge::getTarget() {
> +	return _target;
> +}
> ...
> 
> Trivial accessors should be defined inline.
> 
> -Andy

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20101208/b3583233/attachment.html>


More information about the llvm-dev mailing list