Revert r256277 and r256279.

Some of the bots failed again.

llvm-svn: 256280
This commit is contained in:
Akira Hatanaka 2015-12-22 20:29:09 +00:00
parent 3f1bf25db1
commit 9c05cc5670
9 changed files with 38 additions and 232 deletions

View File

@ -33,7 +33,6 @@ class AttributeSetImpl;
class AttributeSetNode;
class Constant;
template<typename T> struct DenseMapInfo;
class Function;
class LLVMContext;
class Type;
@ -533,13 +532,6 @@ namespace AttributeFuncs {
/// \brief Which attributes cannot be applied to a type.
AttrBuilder typeIncompatible(Type *Ty);
/// \returns Return true if the two functions have compatible target-independent
/// attributes for inlining purposes.
bool areInlineCompatible(const Function &Caller, const Function &Callee);
/// \brief Merge caller's and callee's attributes.
void mergeAttributesForInlining(Function &Caller, const Function &Callee);
} // end AttributeFuncs namespace
} // end llvm namespace

View File

@ -165,28 +165,3 @@ def LessPreciseFPMAD : StrBoolAttr<"less-precise-fpmad">;
def NoInfsFPMath : StrBoolAttr<"no-infs-fp-math">;
def NoNansFPMath : StrBoolAttr<"no-nans-fp-math">;
def UnsafeFPMath : StrBoolAttr<"unsafe-fp-math">;
class CompatRule<string F> {
// The name of the function called to check the attribute of the caller and
// callee and decide whether inlining should be allowed. The function's
// signature must match "bool(const Function&, const Function &)", where the
// first parameter is the reference to the caller and the second parameter is
// the reference to the callee. It must return false if the attributes of the
// caller and callee are incompatible, and true otherwise.
string CompatFunc = F;
}
def : CompatRule<"isEqual<SanitizeAddressAttr>">;
def : CompatRule<"isEqual<SanitizeThreadAttr>">;
def : CompatRule<"isEqual<SanitizeMemoryAttr>">;
class MergeRule<string F> {
// The name of the function called to merge the attributes of the caller and
// callee. The function's signature must match
// "void(Function&, const Function &)", where the first parameter is the
// reference to the caller and the second parameter is the reference to the
// callee.
string MergeFunc = F;
}
def : MergeRule<"adjustCallerSSPLevel">;

View File

@ -1362,7 +1362,9 @@ static bool functionsHaveCompatibleAttributes(Function *Caller,
Function *Callee,
TargetTransformInfo &TTI) {
return TTI.areInlineCompatible(Caller, Callee) &&
AttributeFuncs::areInlineCompatible(*Caller, *Callee);
attributeMatches(Caller, Callee, Attribute::SanitizeAddress) &&
attributeMatches(Caller, Callee, Attribute::SanitizeMemory) &&
attributeMatches(Caller, Callee, Attribute::SanitizeThread);
}
InlineCost InlineCostAnalysis::getInlineCost(CallSite CS, Function *Callee,

View File

@ -14,7 +14,6 @@
//===----------------------------------------------------------------------===//
#include "llvm/IR/Attributes.h"
#include "llvm/IR/Function.h"
#include "AttributeImpl.h"
#include "LLVMContextImpl.h"
#include "llvm/ADT/STLExtras.h"
@ -1432,80 +1431,3 @@ AttrBuilder AttributeFuncs::typeIncompatible(Type *Ty) {
return Incompatible;
}
template<typename AttrClass>
static bool isEqual(const Function &Caller, const Function &Callee) {
return Caller.getFnAttribute(AttrClass::getKind()) ==
Callee.getFnAttribute(AttrClass::getKind());
}
/// \brief Compute the logical AND of the attributes of the caller and the
/// callee.
///
/// This function sets the caller's attribute to false if the callee's attribute
/// is false.
template<typename AttrClass>
static void setAND(Function &Caller, const Function &Callee) {
if (AttrClass::isSet(Caller, AttrClass::getKind()) &&
!AttrClass::isSet(Callee, AttrClass::getKind()))
AttrClass::set(Caller, AttrClass::getKind(), false);
}
/// \brief Compute the logical OR of the attributes of the caller and the
/// callee.
///
/// This function sets the caller's attribute to true if the callee's attribute
/// is true.
template<typename AttrClass>
static void setOR(Function &Caller, const Function &Callee) {
if (!AttrClass::isSet(Caller, AttrClass::getKind()) &&
AttrClass::isSet(Callee, AttrClass::getKind()))
AttrClass::set(Caller, AttrClass::getKind(), true);
}
/// \brief If the inlined function had a higher stack protection level than the
/// calling function, then bump up the caller's stack protection level.
static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) {
// If upgrading the SSP attribute, clear out the old SSP Attributes first.
// Having multiple SSP attributes doesn't actually hurt, but it adds useless
// clutter to the IR.
AttrBuilder B;
B.addAttribute(Attribute::StackProtect)
.addAttribute(Attribute::StackProtectStrong)
.addAttribute(Attribute::StackProtectReq);
AttributeSet OldSSPAttr = AttributeSet::get(Caller.getContext(),
AttributeSet::FunctionIndex,
B);
if (Callee.hasFnAttribute(Attribute::SafeStack)) {
Caller.removeAttributes(AttributeSet::FunctionIndex, OldSSPAttr);
Caller.addFnAttr(Attribute::SafeStack);
} else if (Callee.hasFnAttribute(Attribute::StackProtectReq) &&
!Caller.hasFnAttribute(Attribute::SafeStack)) {
Caller.removeAttributes(AttributeSet::FunctionIndex, OldSSPAttr);
Caller.addFnAttr(Attribute::StackProtectReq);
} else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) &&
!Caller.hasFnAttribute(Attribute::SafeStack) &&
!Caller.hasFnAttribute(Attribute::StackProtectReq)) {
Caller.removeAttributes(AttributeSet::FunctionIndex, OldSSPAttr);
Caller.addFnAttr(Attribute::StackProtectStrong);
} else if (Callee.hasFnAttribute(Attribute::StackProtect) &&
!Caller.hasFnAttribute(Attribute::SafeStack) &&
!Caller.hasFnAttribute(Attribute::StackProtectReq) &&
!Caller.hasFnAttribute(Attribute::StackProtectStrong))
Caller.addFnAttr(Attribute::StackProtect);
}
#define GET_ATTR_COMPAT_FUNC
#include "AttributesCompatFunc.inc"
bool AttributeFuncs::areInlineCompatible(const Function &Caller,
const Function &Callee) {
return hasCompatibleFnAttrs(Caller, Callee);
}
void AttributeFuncs::mergeAttributesForInlining(Function &Caller,
const Function &Callee) {
mergeFnAttrs(Caller, Callee);
}

View File

@ -1 +0,0 @@
include "llvm/IR/Attributes.td"

View File

@ -1,7 +1,3 @@
set(LLVM_TARGET_DEFINITIONS AttributesCompatFunc.td)
tablegen(LLVM AttributesCompatFunc.inc -gen-attrs)
add_public_tablegen_target(AttributeCompatFuncTableGen)
add_llvm_library(LLVMCore
AsmWriter.cpp
Attributes.cpp

View File

@ -11,19 +11,16 @@ LIBRARYNAME = LLVMCore
BUILD_ARCHIVE = 1
BUILT_SOURCES = $(PROJ_OBJ_ROOT)/include/llvm/IR/Intrinsics.gen \
$(PROJ_OBJ_ROOT)/include/llvm/IR/Attributes.inc \
$(PROJ_OBJ_ROOT)/lib/IR/AttributesCompatFunc.inc
$(PROJ_OBJ_ROOT)/include/llvm/IR/Attributes.inc
include $(LEVEL)/Makefile.common
GENFILE:=$(PROJ_OBJ_ROOT)/include/llvm/IR/Intrinsics.gen
ATTRINCFILE:=$(PROJ_OBJ_ROOT)/include/llvm/IR/Attributes.inc
ATTRCOMPATFUNCINCFILE:=$(PROJ_OBJ_ROOT)/lib/IR/AttributesCompatFunc.inc
INTRINSICTD := $(PROJ_SRC_ROOT)/include/llvm/IR/Intrinsics.td
INTRINSICTDS := $(wildcard $(PROJ_SRC_ROOT)/include/llvm/IR/Intrinsics*.td)
ATTRIBUTESTD := $(PROJ_SRC_ROOT)/include/llvm/IR/Attributes.td
ATTRCOMPATFUNCTD := $(PROJ_SRC_ROOT)/lib/IR/AttributesCompatFunc.td
$(ObjDir)/Intrinsics.gen.tmp: $(ObjDir)/.dir $(INTRINSICTDS) $(LLVM_TBLGEN)
$(Echo) Building Intrinsics.gen.tmp from Intrinsics.td
@ -43,15 +40,6 @@ $(ATTRINCFILE): $(ObjDir)/Attributes.inc.tmp $(PROJ_OBJ_ROOT)/include/llvm/IR/.d
$(EchoCmd) Updated Attributes.inc because Attributes.inc.tmp \
changed significantly. )
$(ObjDir)/AttributesCompatFunc.inc.tmp: $(ObjDir)/.dir $(ATTRCOMPATFUNCTD) $(LLVM_TBLGEN)
$(Echo) Building AttributesCompatFunc.inc.tmp from $(ATTRCOMPATFUNCTD)
$(Verb) $(LLVMTableGen) $(call SYSPATH, $(ATTRCOMPATFUNCTD)) -o $(call SYSPATH, $@) -gen-attrs
$(ATTRCOMPATFUNCINCFILE): $(ObjDir)/AttributesCompatFunc.inc.tmp $(PROJ_OBJ_ROOT)/include/llvm/IR/.dir
$(Verb) $(CMP) -s $@ $< || ( $(CP) $< $@ && \
$(EchoCmd) Updated AttributesCompatFunc.inc because AttributesCompatFunc.inc.tmp \
changed significantly. )
install-local:: $(GENFILE)
$(Echo) Installing $(DESTDIR)$(PROJ_includedir)/llvm/IR/Intrinsics.gen
$(Verb) $(DataInstall) $(GENFILE) $(DESTDIR)$(PROJ_includedir)/llvm/IR/Intrinsics.gen
@ -59,7 +47,3 @@ install-local:: $(GENFILE)
install-local:: $(ATTRINCFILE)
$(Echo) Installing $(DESTDIR)$(PROJ_includedir)/llvm/IR/Attributes.inc
$(Verb) $(DataInstall) $(ATTRINCFILE) $(DESTDIR)$(PROJ_includedir)/llvm/IR/Attributes.inc
install-local:: $(ATTRCOMPATFUNCINCFILE)
$(Echo) Installing $(DESTDIR)$(PROJ_libdir)/IR/AttributesCompatFunc.inc
$(Verb) $(DataInstall) $(ATTRCOMPATFUNCINCFILE) $(DESTDIR)$(PROJ_libdir)/IR/AttributesCompatFunc.inc

View File

@ -86,6 +86,39 @@ void Inliner::getAnalysisUsage(AnalysisUsage &AU) const {
typedef DenseMap<ArrayType*, std::vector<AllocaInst*> >
InlinedArrayAllocasTy;
/// \brief If the inlined function had a higher stack protection level than the
/// calling function, then bump up the caller's stack protection level.
static void AdjustCallerSSPLevel(Function *Caller, Function *Callee) {
// If upgrading the SSP attribute, clear out the old SSP Attributes first.
// Having multiple SSP attributes doesn't actually hurt, but it adds useless
// clutter to the IR.
AttrBuilder B;
B.addAttribute(Attribute::StackProtect)
.addAttribute(Attribute::StackProtectStrong)
.addAttribute(Attribute::StackProtectReq);
AttributeSet OldSSPAttr = AttributeSet::get(Caller->getContext(),
AttributeSet::FunctionIndex,
B);
if (Callee->hasFnAttribute(Attribute::SafeStack)) {
Caller->removeAttributes(AttributeSet::FunctionIndex, OldSSPAttr);
Caller->addFnAttr(Attribute::SafeStack);
} else if (Callee->hasFnAttribute(Attribute::StackProtectReq) &&
!Caller->hasFnAttribute(Attribute::SafeStack)) {
Caller->removeAttributes(AttributeSet::FunctionIndex, OldSSPAttr);
Caller->addFnAttr(Attribute::StackProtectReq);
} else if (Callee->hasFnAttribute(Attribute::StackProtectStrong) &&
!Caller->hasFnAttribute(Attribute::SafeStack) &&
!Caller->hasFnAttribute(Attribute::StackProtectReq)) {
Caller->removeAttributes(AttributeSet::FunctionIndex, OldSSPAttr);
Caller->addFnAttr(Attribute::StackProtectStrong);
} else if (Callee->hasFnAttribute(Attribute::StackProtect) &&
!Caller->hasFnAttribute(Attribute::SafeStack) &&
!Caller->hasFnAttribute(Attribute::StackProtectReq) &&
!Caller->hasFnAttribute(Attribute::StackProtectStrong))
Caller->addFnAttr(Attribute::StackProtect);
}
/// If it is possible to inline the specified call site,
/// do so and update the CallGraph for this operation.
///
@ -113,7 +146,7 @@ static bool InlineCallIfPossible(Pass &P, CallSite CS, InlineFunctionInfo &IFI,
if (!InlineFunction(CS, IFI, &AAR, InsertLifetime))
return false;
AttributeFuncs::mergeAttributesForInlining(*Caller, *Callee);
AdjustCallerSSPLevel(Caller, Callee);
// Look at all of the allocas that we inlined through this call site. If we
// have already inlined other allocas through other calls into this function,

View File

@ -27,12 +27,6 @@ public:
private:
void emitTargetIndependentEnums(raw_ostream &OS);
void emitFnAttrCompatCheck(raw_ostream &OS, bool IsStringAttr);
void printEnumAttrClasses(raw_ostream &OS,
const std::vector<Record *> &Records);
void printStrBoolAttrClasses(raw_ostream &OS,
const std::vector<Record *> &Records);
RecordKeeper &Records;
};
@ -52,99 +46,8 @@ void Attributes::emitTargetIndependentEnums(raw_ostream &OS) {
OS << "#endif\n";
}
void Attributes::emitFnAttrCompatCheck(raw_ostream &OS, bool IsStringAttr) {
OS << "#ifdef GET_ATTR_COMPAT_FUNC\n";
OS << "#undef GET_ATTR_COMPAT_FUNC\n";
OS << "struct EnumAttr {\n";
OS << " static bool isSet(const Function &Fn,\n";
OS << " Attribute::AttrKind Kind) {\n";
OS << " return Fn.hasFnAttribute(Kind);\n";
OS << " }\n\n";
OS << " static void set(Function &Fn,\n";
OS << " Attribute::AttrKind Kind, bool Val) {\n";
OS << " if (Val)\n";
OS << " Fn.addFnAttr(Kind);\n";
OS << " else\n";
OS << " Fn.removeFnAttr(Kind);\n";
OS << " }\n";
OS << "};\n\n";
OS << "struct StrBoolAttr {\n";
OS << " static bool isSet(const Function &Fn,\n";
OS << " StringRef Kind) {\n";
OS << " auto A = Fn.getFnAttribute(Kind);\n";
OS << " return A.getValueAsString().equals(\"true\");\n";
OS << " }\n\n";
OS << " static void set(Function &Fn,\n";
OS << " StringRef Kind, bool Val) {\n";
OS << " Fn.addFnAttr(Kind, Val ? \"true\" : \"false\");\n";
OS << " }\n";
OS << "};\n\n";
printEnumAttrClasses(OS ,Records.getAllDerivedDefinitions("EnumAttr"));
printStrBoolAttrClasses(OS , Records.getAllDerivedDefinitions("StrBoolAttr"));
OS << "static inline bool hasCompatibleFnAttrs(const Function &Caller,\n"
<< " const Function &Callee) {\n";
OS << " bool Ret = true;\n\n";
std::vector<Record *> CompatRules =
Records.getAllDerivedDefinitions("CompatRule");
for (auto *Rule : CompatRules) {
StringRef FuncName = Rule->getValueAsString("CompatFunc");
OS << " Ret &= " << FuncName << "(Caller, Callee);\n";
}
OS << "\n";
OS << " return Ret;\n";
OS << "}\n\n";
std::vector<Record *> MergeRules =
Records.getAllDerivedDefinitions("MergeRule");
OS << "static inline void mergeFnAttrs(Function &Caller,\n"
<< " const Function &Callee) {\n";
for (auto *Rule : MergeRules) {
StringRef FuncName = Rule->getValueAsString("MergeFunc");
OS << " " << FuncName << "(Caller, Callee);\n";
}
OS << "}\n\n";
OS << "#endif\n";
}
void Attributes::printEnumAttrClasses(raw_ostream &OS,
const std::vector<Record *> &Records) {
OS << "// EnumAttr classes\n";
for (const auto *R : Records) {
OS << "struct " << R->getName() << "Attr : EnumAttr {\n";
OS << " static enum Attribute::AttrKind getKind() {\n";
OS << " return llvm::Attribute::" << R->getName() << ";\n";
OS << " }\n";
OS << "};\n";
}
OS << "\n";
}
void Attributes::printStrBoolAttrClasses(raw_ostream &OS,
const std::vector<Record *> &Records) {
OS << "// StrBoolAttr classes\n";
for (const auto *R : Records) {
OS << "struct " << R->getName() << "Attr : StrBoolAttr {\n";
OS << " static const char *getKind() {\n";
OS << " return \"" << R->getValueAsString("AttrString") << "\";\n";
OS << " }\n";
OS << "};\n";
}
OS << "\n";
}
void Attributes::emit(raw_ostream &OS) {
emitTargetIndependentEnums(OS);
emitFnAttrCompatCheck(OS, false);
}
namespace llvm {