Page MenuHomePhabricator

Allow separation of declarations and definitions in <Target>ISelDAGToDAG.inc
ClosedPublic

Authored by kparzysz on Nov 3 2017, 7:05 AM.

Details

Summary

This patch adds the ability to include the member function declarations in the instruction selector class separately from the member bodies.

Defining GET_DAGISEL_DECL macro to any value will only include the member declarations. To include bodies, define GET_DAGISEL_BODY macro to be the selector class name. Example:

class FooDAGToDAGISel : public SelectionDAGISel {
  // Pull in declarations only.
  #define GET_DAGISEL_DECL
  #include "FooISelDAGToDAG.inc"
};

// Include the function bodies (with names qualified with the provided
// class name).
#define GET_DAGISEL_BODY FooDAGToDAGISel
#include "FooISelDAGToDAG.inc"

When neither of the two macros are defined, the function bodies are emitted inline (in the same way as before this patch).

Diff Detail

Repository
rL LLVM

Event Timeline

kparzysz created this revision.Nov 3 2017, 7:05 AM

Here's an example of what an .inc file will look like:

/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
|*                                                                            *|
|* DAG Instruction Selector for the Hexagon target                            *|
|*                                                                            *|
|* Automatically generated file, do not edit!                                 *|
|*                                                                            *|
\*===----------------------------------------------------------------------===*/

// *** NOTE: This file is #included into the middle of the target
// *** instruction selector class.  These functions are really methods.

// If GET_DAGISEL_DECL is #defined with any value, only function
// declarations will be included when this file is included.
// If GET_DAGISEL_BODY is #defined, its value should be the name of
// the instruction selector class. Function bodies will be emitted
// and each function's name will be qualified with the name of the
// class.
//
// When neither of the GET_DAGISEL* macros is defined, the functions
// are emitted inline.

#if defined(GET_DAGISEL_DECL) && defined(GET_DAGISEL_BODY)
#error GET_DAGISEL_DECL and GET_DAGISEL_BODY cannot be both defined, undef both for inline definitions
#endif

#ifdef GET_DAGISEL_BODY
#define LOCAL_DAGISEL_STRINGIZE(X) LOCAL_DAGISEL_STRINGIZE_(X)
#define LOCAL_DAGISEL_STRINGIZE_(X) #X
static_assert(sizeof(LOCAL_DAGISEL_STRINGIZE(GET_DAGISEL_BODY)) > 1,
   "GET_DAGISEL_BODY is empty: it should be defined with the class name");
#undef LOCAL_DAGISEL_STRINGIZE_
#undef LOCAL_DAGISEL_STRINGIZE
#endif

#if !defined(GET_DAGISEL_DECL) && !defined(GET_DAGISEL_BODY)
#define DAGISEL_INLINE 1
#else
#define DAGISEL_INLINE 0
#endif

#if !DAGISEL_INLINE
#define DAGISEL_CLASS_COLONCOLON GET_DAGISEL_BODY ::
#else
#define DAGISEL_CLASS_COLONCOLON
#endif

#ifdef GET_DAGISEL_DECL
void SelectCode(SDNode *N);
#endif
#if defined(GET_DAGISEL_BODY) || DAGISEL_INLINE
void DAGISEL_CLASS_COLONCOLON SelectCode(SDNode *N)
{
  [...]
}
#endif // GET_DAGISEL_BODY
#ifdef GET_DAGISEL_DECL
bool CheckPatternPredicate(unsigned PredNo) const override;
#endif
#if defined(GET_DAGISEL_BODY) || DAGISEL_INLINE
bool DAGISEL_CLASS_COLONCOLON CheckPatternPredicate(unsigned PredNo) const
#if DAGISEL_INLINE
  override
#endif
{
  [...]
}

// etc.


#ifdef DAGISEL_INLINE
#undef DAGISEL_INLINE
#endif
#ifdef DAGISEL_CLASS_COLONCOLON
#undef DAGISEL_CLASS_COLONCOLON
#endif
#ifdef GET_DAGISEL_DECL
#undef GET_DAGISEL_DECL
#endif
#ifdef GET_DAGISEL_BODY
#undef GET_DAGISEL_BODY
#endif
This revision is now accepted and ready to land.Nov 10 2017, 9:22 AM
This revision was automatically updated to reflect the committed changes.