I have the following macro,
#define assert(exp) ({ if(! (exp) ) __builtin_unreachable(); })
However it turned out that some (minority of) expressions generate code (gcc Redhat 5.2.1-2 -O2 -std=c++17).
That is certainly the case for assert(syscall(GET_TID)==tid);
And I assume would be the case for non-pure functions in general.
My second take:
#define assume(exp) \
({ \
auto __a = [&] () __attribute__((pure)) -> int { \
return !! (exp); \
}; \
if (!__a()) \
__builtin_unreachable(); \
})
This meant to either fool compiler into believing expression is pure to optimize it out or generate error if not. Unfortunately, no improvement seen.
Question.
Is there a way to force compiler to optimize out all the code.
Or, alternatively can I detect the problem at compile time: that is whether expression generates code or is non-pure. Compile/link error is acceptable but I wish to think of these as last resort.
Update: More explanation.
I want compiler to utilise hints from the expressions to optimize code further down the line.
I want no extra code to be produced at the place assumption is checked (or at least be able to confirm that).
From checking briefly compiler output.
It achieves (1) pretty neatly in many cases provided that expression is useful and transparent for the compiler (e.g. variable comparison, inline function calls, no side effects).
With (2) there is a problem. Compiler leaves code where expressions are non-transparent (or non-pure). These are actually the exact expressions compiler is unable to derive hints from.
I want to stop compiler doing (2) or generate warning on such an occurrence.
No, you can not make assert to ignore conditions which may contain side-effects (e.g. function calls) which is the main reason why they can't be used as optimization hints.
You'd need to modify compiler frontend to get this sort of functionality (I've submitted a GCC patch for this a while ago here).
Related
I'm developing an online judge system for programming contests. Since C/C++ inline assembly is not allowed in certain programming contests, I would like to add the same restriction to my system.
I would like to let GCC produce an error when compiling a C/C++ program containing inline assembly, so that any program containing inline assembly will be rejected. Is there a way to achieve that?
Note: disabling inline assembly is just for obeying the rules, not for security concerns.
Is there a way to disable inline assembler in GCC?
Yes there are a couple of methods; none useful for security, only guard-rails that could be worked around intentionally, but will stop people from accidentally using asm in places they didn't realize they shouldn't.
Turn off the asm keyword in the compiler (C only)
To do it in compilation phase, use the parameter -fno-asm. However, keep in mind that this will only affect asm for C, not C++. And not __asm__ or __asm for either language.
Documentation:
-fno-asm
Do not recognize "asm", "inline" or "typeof" as a keyword, so that code can use these words as identifiers. You can use the keywords "__asm__", "__inline__" and "__typeof__" instead. -ansi implies -fno-asm.
In C++ , this switch only affects the "typeof" keyword, since "asm" and "inline" are standard keywords. You may want to use the -fno-gnu-keywords flag instead, which has the same effect. In C99 mode (-std=c99 or -std=gnu99), this switch only affects the "asm" and "typeof" keywords, since "inline" is a standard keyword in ISO C99.
Define the keyword as a macro
You can use the parameters -Dasm=error -D__asm__=error -D__asm=error
Note that this construction is generic. What it does is to create macros. It works pretty much like a #define. The documentation says:
-D name=definition
The contents of definition are tokenized and processed as if they appeared during translation phase three in a #define directive. In particular, the definition will be truncated by embedded newline characters.
...
So what it does is simply to change occurrences of asm, __asm, or __asm__ to error. This is done in the preprocessor phase. You don't have to use error. Just pick anything that will not compile.
Use a macro that fires during compilation
A way to solve it in compilation phase by using a macro, as suggested in comments by zwol, you can use -D'asm(...)=_Static_assert(0,"inline assembly not allowed")'. This will also solve the problem if there exist an identifier called error.
Note: This method requires -std=c11 or higher.
Using grep before using gcc
Yet another way that may be the solution to your problem is to just do a grep in the root of the source tree before compiling:
grep -nr "asm"
This will also catch __asm__ but it may give false positives, for instance is you have a string literal, identifier or comment containing the substring "asm". But in your case you could solve this problem by also forbidding any occurrence of that string anywhere in the source code. Just change the rules.
Possible unexpected problems
Note that disabling assembly can cause other problems. For instance, I could not use stdio.h with this option. It is common that system headers contains inline assembly code.
A way to cheat above methods
Aside from the trivial #undef __asm__, it is possible to execute strings as machine code. See this answer for an example: https://stackoverflow.com/a/18477070/6699433
A piece of the code from the link above:
/* our machine code */
char code[] = {0x55,0x48,0x89,0xe5,0x89,0x7d,0xfc,0x48,
0x89,0x75,0xf0,0xb8,0x2a,0x00,0x00,0x00,0xc9,0xc3,0x00};
/* copy code to executable buffer */
void *buf = mmap (0,sizeof(code),PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_ANON,-1,0);
memcpy (buf, code, sizeof(code));
/* run code */
int i = ((int (*) (void))buf)();
The code above is only intended to give a quick idea of how to trick the rules OP has stated. It is not intended to be a good example of how to actually perform it in reality. Furthermore, the code is not mine. It is just a short code quote from the link I supplied. If you have ideas about how to improve it, then please comment on 4pie0:s original post instead.
I have a very long code, which is being called millions of time,
I have noticed that if I change all the macros into inline functions the code runs a lot faster.
Can you explain why this is? Aren't macros only a text replacement? As opposed to inline functions which can be a call to a function?
A macro is a text sustitution and will as such generally produce more executable code. Every time you call a macro, code is inserted (well, not necessarily, the macro could be empty... but in principle).
Inline functions, on the other hand, may work the same as macros, but they might also not be inlined at all.
In general, the inline keyword is rather a weak hint than a requirement anyway, compilers will nowadays judiciously inline functions (or will abstain from doing so) based on heuristics, mostly the number of pseudo-instructions.
Inline functions may thus cause the compiler to not inline the function at all, or inline it a couple of times and then call it non-inined in addition.
Surprisingly, not inlining may actually be faster than inlining, since it reduces overall code size and thus the number of cache and TLB misses.
This will depend on the particular macro and function call that you are using. A particular macro can actually compile to a longer set of operations than the inline function. It is often better not to use a macro for certain processes. The inline function will allow the compiler to type check and optimize the various processes. Macros will be subject to a number of errors and can actually cause various inefficiencies (such as by having to move variables in and out of storage).
In any case, since you actually see this happening in your code, you can tell that the compiler is able to optimize your inline code rather than blindly put in the text expansion.
Note that a google search 'macros vs inline' shows a number of discussions of this.
Apart from forcing inlining, macros can also be detrimental to speed if they are not carefully written not to evaluate their arguments twice. Take for example this little function-like macro and its inline function equivalent:
#define square(x) ((x)*(x))
inline long square(long x) { return x*x; }
Now, when you call them with a variable square(foo), they are equivalent. The macro vesion expands to ((foo)*(foo)), which is one multiplication just like the function if it's inlined.
However, if you call them with square(expensiveComputation(foo)), the result of the macro is, that expensiveComputation() is called twice. The inline function, in contrast, behaves like any function: its argument is evaluated once before the body of the function is executed.
Of course, you could write the macro using the gnu extension of compound statements (see http://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html for documentation on this) to avoid double evaluation like this:
#define square(x) ({ \
long square_temp_variable = (x); \
square_temp_variable*square_temp_variable; \
})
But this is a lot of hassle, and it makes the code unportable. So, better stick with inline functions.
at general it is a good advise to replace function style macros by inline functions wherever this is possible.
not only you ged rit of some nasty traps a = MIN(i++, 50) for example you also gain typesafety and as already stated in some comments you avoid multiple evaluation of arguements, that may have very bad influence on performance.
Once reading v8.h in V8 engine code, I could find the following macro.
#define TYPE_CHECK(T, S) \
while (false) { \
*(static_cast<T* volatile*>(0)) = static_cast<S*>(0); \
}
I know that this is to check the type S is compatible with the type T. In the statement, how can the execution flow enter the while loop? while(false) means that condition is always false. Thus, the statement in while loop will never be executed.
As a result, the macro is not always usable, is it?
As a result, the macro is not always usable, is it?
The macro is always usable. The intent is to produce a compile-time error or warning (namely that one type is not compatible with another).
The purpose of wrapping it in while (false) is to prevent the code ever executing at runtime - and with modern compilers the code probably never makes it in to the final binary (optimised out).
If you want to know more about this technique, read up on static assertions.
We have a macro for signalling errors in a common utilities library that goes like this:
#define OurMacro( condition ) \
if( condition ) { \
} else { \
CallExternalFunctionThatWillThrowAnException( parametersListHere ); \
} \
What I refer to as parametersListHere is a comma-separated list of constants and macros that is populated by the compiler at each macro expansion.
That function call always resolves into a call - the function implementation is not exposed to the compiler. The function has six parameters and in debug configuration all of them have meaningful values, while in release configuration only two have meaningful values and others are passed the same default values.
Normally the condition will hold true, so I don't care how fast the invokation is, I only care about the code bloat. Calling that function with 6 parameters requires seven x86 instruction (6 pushes and one call), and clearly 4 of those pushes can be avoided if the function signature is changed to have two parameters only - this can be done by introducing an intermediate "gate" function implemented in such way its implementation is not visible to the compiler.
I need to estimate whether I should insist on that change. So far the primary improvement I expect is that reducing the number of parameters will drop 4 instructions on each invokation which means that the code surrounding the macro expansion will become smaller and the compiler will inline it more likely and optimize the emitted code further.
How can I estimate that without actually trying and recompiling all our code and carefully analyzing the emitted code? Every time I read about inline there's a statement that the compiler decides whether to inline the function.
Can I see some exact set of rules of how the function internals influence compiler decision on inlining?
GCC has a fairly large set of options that expose how their process works, documented here. It's of course not exact, given that it will be tweaked over time and it's CPU-dependent.
The first rule is "their body is smaller than expected function call code".
A second rule is "static functions called once".
There are also parameters affecting the inling process, e.g. max-inline-insns-single. An insn is a pseudo-instruction in the GCC compiler, and is used here as a measure of function complexity. The documentation of parameter max-inline-insns-auto makes it clear that manually declaring a function inline might cause it to be considered for inlining even if it is too big for automatic inlining.
Inlining isn't a all-or-nothing process, since there's a -fpartial-inlining flag.
Of course, you can't consider inlining in isolation. Common Subexpression Elimination (CSE) makes code simpler. It's an optimization pass that may make a function small enough to be inlined. After inlining, new common subexpressions may be discovered so the CSE pass should be run again, which in turn might trigger further inlining. And CSE isn't the only optimization that needs rerunning.
The rules on what functions get inlined and under what conditions (e.g. selected optimization level) are specific to each compiler, so I suggest you check your compiler's documentation. However, a function that just forwards to another function (as you propose) should be a good candidate for inlining by any compiler that supports it.
Some compilers have a mechanism whereby you can flag that you really want a function to be inlined, e.g. MSVC++ has __forceinline.
If you are using Visual C++, you can use __forceinline to force the compiler to inline a function.
When implementing stubs etc. you want to avoid "unused variable" warnings. I've come across a few alternatives of UNUSED() macros over the years, but never one which either is proven to work for "all" compilers, or one which by standard is air tight.
Or are we stuck with #ifdef blocks for each build platform?
EDIT: Due to a number of answers with non c-compliant alternatives, I'd like to clarify that I'm looking for a definition which is valid for both C and C++, all flavours etc.
According to this answer by user GMan the typical way is to cast to void:
#define UNUSED(x) (void)(x)
but if x is marked as volatile that would enforce reading from the variable and thus have a side effect and so the actual way to almost guarantee a no-op and suppress the compiler warning is the following:
// use expression as sub-expression,
// then make type of full expression int, discard result
#define UNUSED(x) (void)(sizeof((x), 0))
In C++, just comment out the names.
void MyFunction(int /* name_of_arg1 */, float /* name_of_arg2*/)
{
...
}
The universal way is not to turn on warnings options that spam warnings for clearly-correct code. Any "unused variable" warning option that includes function arguments in its analysis is simply wrong and should be left off. Don't litter your code with ugliness to quiet broken compilers.
You might also try sending a bug report to the compiler maintainer/vendor.