Creates a global variable containing preliminary information
for the cache-fragmentation tool runtime.
Passes a pointer to the variable (null if no variable is created) to the
compilation unit init and exit routines in the runtime.
Differential D20541
[esan|cfrag] Create the skeleton of cfrag variable for the runtime zhaoqin on May 23 2016, 2:48 PM. Authored by
Details Creates a global variable containing preliminary information Passes a pointer to the variable (null if no variable is created) to the
Diff Detail Event Timeline
Comment Actions Do you want me to have a general GV layout for different Tool? int ToolType; const char *UnitName; void *SpecificToolGV; }; Comment Actions
No, I don't think you need a general layout. But you can have a base struct with ToolType at least. This way you'll guarantee that ToolType would always be a first field => no confusion would happened. Optional though. Comment Actions Yes, I agree that would be better. What I worried is how to implement so.
Comment Actions Let's see how this will play out. Will push this decision onto the one adding the second struct type :) Comment Actions Please add a test for the cache fragmentation tool's global variable.
Comment Actions http://reviews.llvm.org/D20542 is the test for the arg passed to runtime.
Comment Actions Yes, I'd like an LLVM test checking we emit the correct tool number. Thanks for working on this. Filipe
Comment Actions In that case, http://reviews.llvm.org/D20488 has add test to check the tool number passed to __esan_init. Comment Actions It's already there, in cache_frag_basic.ll. Re: this change: How about: Gets all the info/adds constants Sets up an array with the information to be placed in the structure Calls into a helper "create a GV for tool init" function (optional if you want to return the GV from the tool-specific function, at the expense of code duplication) That way, each function deals only with one thing. Instead of having dispatch + (some) setup + GV creation all mixed in the same function. The creation of the structure is very easy to read, and you can easily make sure both places (here and compiler-rt) have a matching structure definition. What do you think?
Comment Actions I feel we are going circle here!!!
I am not sure what's the difference from my original CL, where the struct is declared in each tool-specific create GV? StructType *CacheFragType = StructType::get(Int32Ty, IntptrTy, nullptr); ... GlobalVariable *CacheFragGV = new GlobalVariable( M, CacheFragType, true, GlobalVariable::InternalLinkage, ConstantStruct::get(CacheFragType, ConstantInt::get(Int32Ty, Options.ToolType), ConstantExpr::getPointerCast(UnitName, IntptrTy), nullptr)); It seems clearer than pushing a vector in a separate the function and then create the GV without knowing what's inside. Also, how do you guarantee the UnitName would be the first entry if each tool-specific function "Gets all the info/adds constants"?
Comment Actions I don't think we're going full circle. But sorry if I'm hard to understand. Sometimes I might not explain what I would like to have in the best way. Feel free to ask for more details if what I'm asking for seems out of place or seems to go against what I (or others) have said before. In your original CL you had createCacheFragGV which would: This is to create the GV argument, which tools need for getting information from the ESan pass, basically. Out of those, some are not needed (create the struct type. We can use an anonymous struct), some are common to any tool that needs an extra argument (create the struct itself, create the GV), and others are, for now, common to every tool that gets an argument (create the string global for the module). The rest is tool-specific, and is about creating the values to put in the struct. My previous comment was about extracting away the struct + GV creation (and not needing to have a struct type). Your change addressed those two points, and thanks for doing that. But the resulting code, for me, seems to be more confusing than it needs to be. One of the very good things about the clang example I posted was that you just need to look at the temporary array to figure out what exactly the structure that is passed to __esan_init contains. This also makes it easy to add/change fields to that structure (simply add a new llvm::Constant *[] element to the array creation). My opinion is that it's much easier to create the array at a single place than to track down the SmallVector's inserted elements.
The rationale is that each tool knows what things to place in its structure. If it wants to get the UnitName and wants it to be the first thing in the structure, it will place it there. Comment Actions
IMHO, if you know a struct type layout, specify it upfront, i.e., create the struct type, and fill in the entries.
The EmitCheck has a much more work than simply creating a GV, so it makes sense to having a separate place creating the StaticData and then call EmitCheck.
It is easy to add/change fields, but also make it easy to make mistakes, because there is no struct type to check against.
The only reason I change it to Vec is to make sure we can insert UnitName upfront in CreateEsanInitToolGV, and extend the struct in tool specific createGV functions. In summary:
Looks like my original CL was good. Comment Actions I think the commit message could do a better job of explaining that this is just a skeleton data structure being created here. Its contents are not filled in yet for the cache frag tool.
To me this implies it's created the finished data passed to the runtime, which is not true. Adding "skeleton" or something, or "Part 1 of 2" or something would help.
IMHO this is not a useful commit message line and should be removed. Please describe what the new code is doing, not the name of helper routines.
I would suggest removing the function names and describing in prose what is happening. Maybe something like "Adds a global variable containing preliminary information for the runtime. Passes a pointer to the variable to the compilation unit init routine in the runtime. The varable initially contains just the compilation unit name."
|
That Vec in the name feels weird. Why not just ToolInfoData or even ToolData? No need repeating something that's in the type ("saying" that it's a vector).