[llvm-commits] [dragonegg] r120321 - in /dragonegg/trunk: Makefile llvm-convert.cpp llvm-tree.cpp llvm-tree.h llvm-types.cpp
Duncan Sands
baldrick at free.fr
Mon Nov 29 13:36:12 PST 2010
Author: baldrick
Date: Mon Nov 29 15:36:12 2010
New Revision: 120321
URL: http://llvm.org/viewvc/llvm-project?rev=120321&view=rev
Log:
Factorize out various bits of code that give types and values helpful names in
the LLVM IR.
Added:
dragonegg/trunk/llvm-tree.cpp
dragonegg/trunk/llvm-tree.h
Modified:
dragonegg/trunk/Makefile
dragonegg/trunk/llvm-convert.cpp
dragonegg/trunk/llvm-types.cpp
Modified: dragonegg/trunk/Makefile
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Makefile?rev=120321&r1=120320&r2=120321&view=diff
==============================================================================
--- dragonegg/trunk/Makefile (original)
+++ dragonegg/trunk/Makefile Mon Nov 29 15:36:12 2010
@@ -38,7 +38,7 @@
PLUGIN=dragonegg.so
PLUGIN_OBJECTS=llvm-cache.o llvm-convert.o llvm-backend.o llvm-debug.o \
- llvm-types.o bits_and_bobs.o llvm-abi-default.o
+ llvm-types.o bits_and_bobs.o llvm-abi-default.o llvm-tree.o
TARGET_OBJECT=llvm-target.o
TARGET_SOURCE=$(SRC_DIR)/$(shell $(TARGET_UTIL) -p)/llvm-target.cpp
Modified: dragonegg/trunk/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-convert.cpp?rev=120321&r1=120320&r2=120321&view=diff
==============================================================================
--- dragonegg/trunk/llvm-convert.cpp (original)
+++ dragonegg/trunk/llvm-convert.cpp Mon Nov 29 15:36:12 2010
@@ -27,6 +27,7 @@
#include "llvm-abi.h"
#include "llvm-debug.h"
#include "llvm-internal.h"
+#include "llvm-tree.h"
// LLVM headers
#include "llvm/CallingConv.h"
@@ -166,47 +167,11 @@
/// NameValue - Try to name the given value after the given GCC tree node. If
/// the GCC tree node has no sensible name then it does nothing. If the value
/// already has a name then it is not changed.
-static void NameValue(Value *V, tree t, Twine Prefix = Twine(),
- Twine Postfix = Twine()) {
- // If the value already has a name, do not change it.
- if (V->hasName())
- return;
-
- // No sensible name - give up, discarding any pre- and post-fixes.
- if (!t)
- return;
-
- switch (TREE_CODE(t)) {
- default:
- // Unhandled case - give up.
- return;
-
- case CONST_DECL:
- case FIELD_DECL:
- case FUNCTION_DECL:
- case NAMESPACE_DECL:
- case PARM_DECL:
- case VAR_DECL: {
- if (DECL_NAME(t)) {
- StringRef Ident(IDENTIFIER_POINTER(DECL_NAME(t)),
- IDENTIFIER_LENGTH(DECL_NAME(t)));
- V->setName(Prefix + Ident + Postfix);
- return;
- }
- const char *Annotation = TREE_CODE(t) == CONST_DECL ? "C." : "D.";
- Twine UID(DECL_UID(t));
- V->setName(Prefix + Annotation + UID + Postfix);
- return;
- }
-
- case RESULT_DECL:
- V->setName(Prefix + "<retval>" + Postfix);
- return;
-
- case SSA_NAME:
- Twine NameVersion(SSA_NAME_VERSION(t));
- NameValue(V, SSA_NAME_VAR(t), Prefix, "_" + NameVersion + Postfix);
- return;
+static void NameValue(Value *V, tree t) {
+ if (!V->hasName()) {
+ const std::string &Name = getDescriptiveName(t);
+ if (!Name.empty())
+ V->setName(Name);
}
}
@@ -1069,19 +1034,9 @@
gimple stmt = first_stmt(bb);
if (stmt && gimple_code(stmt) == GIMPLE_LABEL) {
tree label = gimple_label_label(stmt);
- if (tree name = DECL_NAME(label)) {
- // If the label has a name then use it.
- StringRef Ident(IDENTIFIER_POINTER(name), IDENTIFIER_LENGTH(name));
- BB->setName(Ident);
- } else if (LABEL_DECL_UID(label) != -1) {
- // If the label has a UID then use it.
- Twine UID(LABEL_DECL_UID(label));
- BB->setName("<L" + UID + ">");
- } else {
- // Otherwise use the generic UID.
- Twine UID(DECL_UID(label));
- BB->setName("<D." + UID + ">");
- }
+ const std::string &LabelName = getDescriptiveName(label);
+ if (!LabelName.empty())
+ BB->setName("<" + LabelName + ">");
} else {
// When there is no label, use the same name scheme as the GCC tree dumps.
Twine Index(bb->index);
Added: dragonegg/trunk/llvm-tree.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-tree.cpp?rev=120321&view=auto
==============================================================================
--- dragonegg/trunk/llvm-tree.cpp (added)
+++ dragonegg/trunk/llvm-tree.cpp Mon Nov 29 15:36:12 2010
@@ -0,0 +1,129 @@
+//===---- llvm-tree.cpp - Utility functions for working with GCC trees ----===//
+//
+// Copyright (C) 2010 Duncan Sands.
+//
+// This file is part of DragonEgg.
+//
+// DragonEgg is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free Software
+// Foundation; either version 2, or (at your option) any later version.
+//
+// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along with
+// DragonEgg; see the file COPYING. If not, write to the Free Software
+// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
+//
+//===----------------------------------------------------------------------===//
+// This file defines utility functions for working with GCC trees.
+//===----------------------------------------------------------------------===//
+
+// Plugin headers
+#include "llvm-tree.h"
+
+// LLVM headers
+#include "llvm/ADT/Twine.h"
+
+// System headers
+#include <gmp.h>
+
+// GCC headers
+extern "C" {
+#include "config.h"
+// Stop GCC declaring 'getopt' as it can clash with the system's declaration.
+#undef HAVE_DECL_GETOPT
+#include "system.h"
+#include "coretypes.h"
+#include "target.h"
+#include "tree.h"
+}
+
+using namespace llvm;
+
+/// concatIfNotEmpty - Concatenate the given strings if they are both non-empty.
+/// Otherwise return the empty string.
+static std::string concatIfNotEmpty(const std::string &Left,
+ const std::string &Right) {
+ if (Left.empty() || Right.empty())
+ return std::string();
+ return Left + Right;
+}
+
+/// getDescriptiveName - Return a helpful name for the given tree, or an empty
+/// string if no sensible name was found. These names are used to make the IR
+/// more readable, and have no official status.
+std::string llvm::getDescriptiveName(tree t) {
+ if (!t) return std::string(); // Occurs when recursing.
+
+ // Name identifier nodes after their contents. This gives the desired effect
+ // when called recursively.
+ if (TREE_CODE(t) == IDENTIFIER_NODE)
+ return std::string(IDENTIFIER_POINTER(t), IDENTIFIER_LENGTH(t));
+
+ // Handle declarations of all kinds.
+ if (DECL_P(t)) {
+ // If the declaration comes with a name then use it.
+ if (DECL_NAME(t)) // Always an identifier node.
+ return std::string(IDENTIFIER_POINTER(DECL_NAME(t)),
+ IDENTIFIER_LENGTH(DECL_NAME(t)));
+ // Use a generic name for function results.
+ if (TREE_CODE(t) == RESULT_DECL)
+ return "<retval>";
+ // Labels have their own numeric unique identifiers.
+ if (TREE_CODE(t) == LABEL_DECL && LABEL_DECL_UID(t) != -1) {
+ Twine LUID(LABEL_DECL_UID(t));
+ return ("L" + LUID).str();
+ }
+ // Otherwise use the generic UID.
+ const char *Annotation = TREE_CODE(t) == CONST_DECL ? "C." : "D.";
+ Twine UID(DECL_UID(t));
+ return (Annotation + UID).str();
+ }
+
+ // Handle types of all kinds.
+ if (TYPE_P(t)) {
+ // If the type comes with a name then use it.
+ const std::string &TypeName = getDescriptiveName(TYPE_NAME(t));
+ if (!TypeName.empty()) {
+ // Annotate the name with a description of the type's class.
+ if (TREE_CODE(t) == ENUMERAL_TYPE)
+ return "enum." + TypeName;
+ if (TREE_CODE(t) == RECORD_TYPE)
+ return "struct." + TypeName;
+ if (TREE_CODE(t) == QUAL_UNION_TYPE)
+ return "qualunion." + TypeName;
+ if (TREE_CODE(t) == UNION_TYPE)
+ return "union." + TypeName;
+ return TypeName;
+ }
+
+ // Try to deduce a useful name.
+ if (TREE_CODE(t) == ARRAY_TYPE)
+ // If the element type is E, name the array E[] (regardless of the number
+ // of dimensions).
+ return concatIfNotEmpty(getDescriptiveName(TREE_TYPE(t)), "[]");
+ if (TREE_CODE(t) == COMPLEX_TYPE)
+ // If the element type is E, name the complex number complex.E.
+ return concatIfNotEmpty("complex.", getDescriptiveName(TREE_TYPE(t)));
+ if (TREE_CODE(t) == POINTER_TYPE)
+ // If the element type is E, name the pointer E*.
+ return concatIfNotEmpty(getDescriptiveName(TREE_TYPE(t)), "*");
+ if (TREE_CODE(t) == REFERENCE_TYPE)
+ // If the element type is E, name the reference E&.
+ return concatIfNotEmpty(getDescriptiveName(TREE_TYPE(t)), "&");
+
+ return TypeName;
+ }
+
+ // Handle SSA names.
+ if (TREE_CODE(t) == SSA_NAME) {
+ Twine NameVersion(SSA_NAME_VERSION(t));
+ return concatIfNotEmpty(getDescriptiveName(SSA_NAME_VAR(t)),
+ ("_" + NameVersion).str());
+ }
+
+ // A mysterious tree, just give up.
+ return std::string();
+}
Added: dragonegg/trunk/llvm-tree.h
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-tree.h?rev=120321&view=auto
==============================================================================
--- dragonegg/trunk/llvm-tree.h (added)
+++ dragonegg/trunk/llvm-tree.h Mon Nov 29 15:36:12 2010
@@ -0,0 +1,40 @@
+//=-- llvm-tree.h - Utility functions for working with GCC trees --*- C++ -*-=//
+//
+// Copyright (C) 2010 Duncan Sands.
+//
+// This file is part of DragonEgg.
+//
+// DragonEgg is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free Software
+// Foundation; either version 2, or (at your option) any later version.
+//
+// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along with
+// DragonEgg; see the file COPYING. If not, write to the Free Software
+// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
+//
+//===----------------------------------------------------------------------===//
+// This file declares utility functions for working with GCC trees.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TREE_H
+#define LLVM_TREE_H
+
+// System headers
+#include <string>
+
+union tree_node;
+
+namespace llvm {
+
+/// getDescriptiveName - Return a helpful name for the given tree, or an empty
+/// string if no sensible name was found. These names are used to make the IR
+/// more readable, and have no official status.
+std::string getDescriptiveName(union tree_node *t);
+
+}
+
+#endif /* LLVM_TREE_H */
Modified: dragonegg/trunk/llvm-types.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-types.cpp?rev=120321&r1=120320&r2=120321&view=diff
==============================================================================
--- dragonegg/trunk/llvm-types.cpp (original)
+++ dragonegg/trunk/llvm-types.cpp Mon Nov 29 15:36:12 2010
@@ -25,6 +25,7 @@
// Plugin headers
#include "llvm-abi.h"
+#include "llvm-tree.h"
extern "C" {
#include "llvm-cache.h"
}
@@ -280,74 +281,6 @@
return isInt64(DECL_FIELD_OFFSET(field_decl), true);
}
-/// NameType - Try to name the given type after the given GCC tree node. If
-/// the GCC tree node has no sensible name then it does nothing.
-static void NameType(const Type *Ty, tree t, Twine Prefix = Twine(),
- Twine Postfix = Twine()) {
- // No sensible name - give up, discarding any pre- and post-fixes.
- if (!t)
- return;
-
- switch (TREE_CODE(t)) {
- default:
- // Unhandled case - give up.
- return;
-
- case ARRAY_TYPE:
- // If the element type is E, name the array E[] (regardless of the number
- // of dimensions).
- for (; TREE_CODE(t) == ARRAY_TYPE; t = TREE_TYPE(t)) ;
- NameType(Ty, t, Prefix, "[]" + Postfix);
- return;
-
- case BOOLEAN_TYPE:
- case COMPLEX_TYPE:
- case ENUMERAL_TYPE:
- case FIXED_POINT_TYPE:
- case FUNCTION_TYPE:
- case INTEGER_TYPE:
- case METHOD_TYPE:
- case QUAL_UNION_TYPE:
- case REAL_TYPE:
- case RECORD_TYPE:
- case UNION_TYPE:
- case VECTOR_TYPE: {
- // If the type has a name then use that, otherwise bail out.
- if (!TYPE_NAME(t))
- return; // Unnamed type.
-
- tree identifier = NULL_TREE;
- if (TREE_CODE(TYPE_NAME(t)) == IDENTIFIER_NODE)
- identifier = TYPE_NAME(t);
- else if (TREE_CODE(TYPE_NAME(t)) == TYPE_DECL)
- identifier = DECL_NAME(TYPE_NAME(t));
-
- if (identifier) {
- const char *Class = "";
- if (TREE_CODE(t) == ENUMERAL_TYPE)
- Class = "enum ";
- if (TREE_CODE(t) == RECORD_TYPE)
- Class = "struct ";
- else if (TREE_CODE(t) == UNION_TYPE)
- Class = "union ";
- StringRef Ident(IDENTIFIER_POINTER(identifier),
- IDENTIFIER_LENGTH(identifier));
- TheModule->addTypeName((Prefix + Class + Ident + Postfix).str(), Ty);
- }
- return;
- }
-
- case POINTER_TYPE:
- // If the element type is E, LLVM already calls this E*.
- return;
-
- case REFERENCE_TYPE:
- // If the element type is E, name the reference E&.
- NameType(Ty, TREE_TYPE(t), Prefix, "&" + Postfix);
- return;
- }
-}
-
/// isBitfield - Returns whether to treat the specified field as a bitfield.
bool isBitfield(tree_node *field_decl) {
if (!DECL_BIT_FIELD(field_decl))
@@ -943,7 +876,15 @@
}
}
- NameType(Ty, type);
+ // Try to give the type a helpful name. There is no point in doing this for
+ // array and pointer types since LLVM automatically gives them a useful name
+ // based on the element type.
+ if (!isa<SequentialType>(Ty)) {
+ const std::string &TypeName = getDescriptiveName(type);
+ if (!TypeName.empty())
+ TheModule->addTypeName(TypeName, Ty);
+ }
+
return Ty;
}
More information about the llvm-commits
mailing list