fix(libc): make sure __init functions are garbage collected

RECLAIM_INIT_CODE is useful to remove code that is only necessary during
boot. However, these functions are generally called once and as such
prime candidates for inlining. When building with LTO, the compiler is
pretty good at inlining every single one, making this option pointless.

So tell the compiler to not inline these functions. This ensures they
are kept separate and they can be garbage collected later. This is
expected to cost a little bit of speed due to the extra branching.

Change-Id: Ie83a9ec8db03cb42139742fc6d728d12ce8549d3
Signed-off-by: Boyan Karatotev <boyan.karatotev@arm.com>
diff --git a/include/lib/libc/cdefs.h b/include/lib/libc/cdefs.h
index 97b7824..5febe9d 100644
--- a/include/lib/libc/cdefs.h
+++ b/include/lib/libc/cdefs.h
@@ -16,12 +16,19 @@
 #define __aligned(x)	__attribute__((__aligned__(x)))
 #define __section(x)	__attribute__((__section__(x)))
 #define __fallthrough	__attribute__((__fallthrough__))
+#define __noinline	__attribute__((__noinline__))
 #if RECLAIM_INIT_CODE
 /*
  * Add each function to a section that is unique so the functions can still
- * be garbage collected
+ * be garbage collected.
+ *
+ * NOTICE: for this to work, these functions will NOT be inlined.
+ * TODO: the noinline attribute can be removed if RECLAIM_INIT_CODE is made
+ * platform agnostic and called after bl31_main(). Then, top-level functions
+ * (those that can't be inlined like bl31_main()) can be annotated with __init
+ * and noinline can be removed.
  */
-#define __init		__section(".text.init." __FILE__ "." __XSTRING(__LINE__))
+#define __init		__section(".text.init." __FILE__ "." __XSTRING(__LINE__)) __noinline
 #else
 #define __init
 #endif