mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-05 14:34:55 +00:00
Rather than having special rules like "intrinsics cannot
throw exceptions", just mark intrinsics with the nounwind attribute. Likewise, mark intrinsics as readnone/readonly and get rid of special aliasing logic (which didn't use anything more than this anyway). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44544 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
4cf4b69330
commit
a3355ffb3d
@ -158,6 +158,16 @@ public:
|
||||
return ParamAttrs && ParamAttrs->paramHasAttr(i, attr);
|
||||
}
|
||||
|
||||
/// @brief Determine if the function does not access memory.
|
||||
bool doesNotAccessMemory() const {
|
||||
return paramHasAttr(0, ParamAttr::ReadNone);
|
||||
}
|
||||
|
||||
/// @brief Determine if the function does not access or only reads memory.
|
||||
bool onlyReadsMemory() const {
|
||||
return doesNotAccessMemory() || paramHasAttr(0, ParamAttr::ReadOnly);
|
||||
}
|
||||
|
||||
/// @brief Determine if the function returns a structure.
|
||||
bool isStructReturn() const {
|
||||
return paramHasAttr(1, ParamAttr::StructRet);
|
||||
|
@ -927,6 +927,21 @@ public:
|
||||
/// @brief Determine whether the call or the callee has the given attribute.
|
||||
bool paramHasAttr(uint16_t i, ParameterAttributes attr) const;
|
||||
|
||||
/// @brief Determine if the call does not access memory.
|
||||
bool doesNotAccessMemory() const {
|
||||
return paramHasAttr(0, ParamAttr::ReadNone);
|
||||
}
|
||||
|
||||
/// @brief Determine if the call does not access or only reads memory.
|
||||
bool onlyReadsMemory() const {
|
||||
return doesNotAccessMemory() || paramHasAttr(0, ParamAttr::ReadOnly);
|
||||
}
|
||||
|
||||
/// @brief Determine if the call cannot unwind.
|
||||
bool isNoUnwind() const {
|
||||
return paramHasAttr(0, ParamAttr::NoUnwind);
|
||||
}
|
||||
|
||||
/// @brief Determine if the call returns a structure.
|
||||
bool isStructReturn() const {
|
||||
// Be friendly and also check the callee.
|
||||
@ -1711,6 +1726,21 @@ public:
|
||||
/// @brief Determine whether the call or the callee has the given attribute.
|
||||
bool paramHasAttr(uint16_t i, ParameterAttributes attr) const;
|
||||
|
||||
/// @brief Determine if the call does not access memory.
|
||||
bool doesNotAccessMemory() const {
|
||||
return paramHasAttr(0, ParamAttr::ReadNone);
|
||||
}
|
||||
|
||||
/// @brief Determine if the call does not access or only reads memory.
|
||||
bool onlyReadsMemory() const {
|
||||
return doesNotAccessMemory() || paramHasAttr(0, ParamAttr::ReadOnly);
|
||||
}
|
||||
|
||||
/// @brief Determine if the call cannot unwind.
|
||||
bool isNoUnwind() const {
|
||||
return paramHasAttr(0, ParamAttr::NoUnwind);
|
||||
}
|
||||
|
||||
/// @brief Determine if the call returns a structure.
|
||||
bool isStructReturn() const {
|
||||
// Be friendly and also check the callee.
|
||||
|
@ -22,6 +22,7 @@ class Type;
|
||||
class FunctionType;
|
||||
class Function;
|
||||
class Module;
|
||||
class ParamAttrsList;
|
||||
|
||||
/// Intrinsic Namespace - This namespace contains an enum with a value for
|
||||
/// every intrinsic/builtin function known by LLVM. These enum values are
|
||||
@ -46,6 +47,10 @@ namespace Intrinsic {
|
||||
///
|
||||
const FunctionType *getType(ID id, const Type **Tys = 0, unsigned numTys = 0);
|
||||
|
||||
/// Intrinsic::getParamAttrs(ID) - Return the attributes for an intrinsic.
|
||||
///
|
||||
const ParamAttrsList *getParamAttrs(ID id);
|
||||
|
||||
/// Intrinsic::getDeclaration(M, ID) - Create or insert an LLVM Function
|
||||
/// declaration for an intrinsic, and return it.
|
||||
Function *getDeclaration(Module *M, ID id, const Type **Tys = 0,
|
||||
|
@ -67,6 +67,12 @@ public:
|
||||
/// paramHasAttr - whether the call or the callee has the given attribute.
|
||||
bool paramHasAttr(uint16_t i, ParameterAttributes attr) const;
|
||||
|
||||
/// @brief Determine if the call does not access memory.
|
||||
bool doesNotAccessMemory() const;
|
||||
|
||||
/// @brief Determine if the call does not access or only reads memory.
|
||||
bool onlyReadsMemory() const;
|
||||
|
||||
/// getType - Return the type of the instruction that generated this call site
|
||||
///
|
||||
const Type *getType() const { return I->getType(); }
|
||||
|
@ -116,13 +116,13 @@ AliasAnalysis::getModRefInfo(StoreInst *S, Value *P, unsigned Size) {
|
||||
AliasAnalysis::ModRefBehavior
|
||||
AliasAnalysis::getModRefBehavior(CallSite CS,
|
||||
std::vector<PointerAccessInfo> *Info) {
|
||||
if (CS.paramHasAttr(0, ParamAttr::ReadNone))
|
||||
if (CS.doesNotAccessMemory())
|
||||
// Can't do better than this.
|
||||
return DoesNotAccessMemory;
|
||||
ModRefBehavior MRB = UnknownModRefBehavior;
|
||||
if (Function *F = CS.getCalledFunction())
|
||||
MRB = getModRefBehavior(F, CS, Info);
|
||||
if (MRB != DoesNotAccessMemory && CS.paramHasAttr(0, ParamAttr::ReadOnly))
|
||||
if (MRB != DoesNotAccessMemory && CS.onlyReadsMemory())
|
||||
return OnlyReadsMemory;
|
||||
return MRB;
|
||||
}
|
||||
@ -130,11 +130,11 @@ AliasAnalysis::getModRefBehavior(CallSite CS,
|
||||
AliasAnalysis::ModRefBehavior
|
||||
AliasAnalysis::getModRefBehavior(Function *F,
|
||||
std::vector<PointerAccessInfo> *Info) {
|
||||
if (F->paramHasAttr(0, ParamAttr::ReadNone))
|
||||
if (F->doesNotAccessMemory())
|
||||
// Can't do better than this.
|
||||
return DoesNotAccessMemory;
|
||||
ModRefBehavior MRB = getModRefBehavior(F, CallSite(), Info);
|
||||
if (MRB != DoesNotAccessMemory && F->paramHasAttr(0, ParamAttr::ReadOnly))
|
||||
if (MRB != DoesNotAccessMemory && F->onlyReadsMemory())
|
||||
return OnlyReadsMemory;
|
||||
return MRB;
|
||||
}
|
||||
|
@ -25,8 +25,6 @@
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/ADT/BitVector.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/GetElementPtrTypeIterator.h"
|
||||
@ -116,9 +114,6 @@ namespace {
|
||||
/// global) or not.
|
||||
bool pointsToConstantMemory(const Value *P);
|
||||
|
||||
virtual ModRefBehavior getModRefBehavior(Function *F, CallSite CS,
|
||||
std::vector<PointerAccessInfo> *Info);
|
||||
|
||||
private:
|
||||
// CheckGEPInstructions - Check two GEP instructions with known
|
||||
// must-aliasing base pointers. This checks to see if the index expressions
|
||||
@ -810,37 +805,5 @@ BasicAliasAnalysis::CheckGEPInstructions(
|
||||
return MayAlias;
|
||||
}
|
||||
|
||||
static ManagedStatic<BitVector> NoMemoryIntrinsics;
|
||||
static ManagedStatic<BitVector> OnlyReadsMemoryIntrinsics;
|
||||
|
||||
AliasAnalysis::ModRefBehavior
|
||||
BasicAliasAnalysis::getModRefBehavior(Function *F, CallSite CS,
|
||||
std::vector<PointerAccessInfo> *Info) {
|
||||
if (!F->isDeclaration()) return UnknownModRefBehavior;
|
||||
|
||||
static bool Initialized = false;
|
||||
if (!Initialized) {
|
||||
NoMemoryIntrinsics->resize(Intrinsic::num_intrinsics);
|
||||
OnlyReadsMemoryIntrinsics->resize(Intrinsic::num_intrinsics);
|
||||
#define GET_MODREF_BEHAVIOR
|
||||
#include "llvm/Intrinsics.gen"
|
||||
#undef GET_MODREF_BEHAVIOR
|
||||
|
||||
Initialized = true;
|
||||
}
|
||||
|
||||
// If this is an intrinsic, we can use lookup tables
|
||||
if (unsigned id = F->getIntrinsicID()) {
|
||||
if (NoMemoryIntrinsics->test(id))
|
||||
return DoesNotAccessMemory;
|
||||
if (OnlyReadsMemoryIntrinsics->test(id))
|
||||
return OnlyReadsMemory;
|
||||
|
||||
return UnknownModRefBehavior;
|
||||
}
|
||||
|
||||
return UnknownModRefBehavior;
|
||||
}
|
||||
|
||||
// Make sure that anything that uses AliasAnalysis pulls in this file...
|
||||
DEFINING_FILE_FOR(BasicAliasAnalysis)
|
||||
|
@ -136,7 +136,7 @@ private:
|
||||
|
||||
// If this function is not defined in this translation unit, it could call
|
||||
// anything.
|
||||
if (F->isDeclaration() && !F->getIntrinsicID())
|
||||
if (F->isDeclaration() && !F->isIntrinsic())
|
||||
Node->addCalledFunction(CallSite(), CallsExternalNode);
|
||||
|
||||
// Loop over all of the users of the function... looking for callers...
|
||||
|
@ -2417,31 +2417,13 @@ void SelectionDAGLowering::visitStore(StoreInst &I) {
|
||||
I.isVolatile(), I.getAlignment()));
|
||||
}
|
||||
|
||||
/// IntrinsicCannotAccessMemory - Return true if the specified intrinsic cannot
|
||||
/// access memory and has no other side effects at all.
|
||||
static bool IntrinsicCannotAccessMemory(unsigned IntrinsicID) {
|
||||
#define GET_NO_MEMORY_INTRINSICS
|
||||
#include "llvm/Intrinsics.gen"
|
||||
#undef GET_NO_MEMORY_INTRINSICS
|
||||
return false;
|
||||
}
|
||||
|
||||
// IntrinsicOnlyReadsMemory - Return true if the specified intrinsic doesn't
|
||||
// have any side-effects or if it only reads memory.
|
||||
static bool IntrinsicOnlyReadsMemory(unsigned IntrinsicID) {
|
||||
#define GET_SIDE_EFFECT_INFO
|
||||
#include "llvm/Intrinsics.gen"
|
||||
#undef GET_SIDE_EFFECT_INFO
|
||||
return false;
|
||||
}
|
||||
|
||||
/// visitTargetIntrinsic - Lower a call of a target intrinsic to an INTRINSIC
|
||||
/// node.
|
||||
void SelectionDAGLowering::visitTargetIntrinsic(CallInst &I,
|
||||
unsigned Intrinsic) {
|
||||
bool HasChain = !IntrinsicCannotAccessMemory(Intrinsic);
|
||||
bool OnlyLoad = HasChain && IntrinsicOnlyReadsMemory(Intrinsic);
|
||||
|
||||
bool HasChain = !I.doesNotAccessMemory();
|
||||
bool OnlyLoad = HasChain && I.onlyReadsMemory();
|
||||
|
||||
// Build the operand list.
|
||||
SmallVector<SDOperand, 8> Ops;
|
||||
if (HasChain) { // If this intrinsic has side-effects, chainify it.
|
||||
|
@ -1551,7 +1551,7 @@ bool CWriter::doInitialization(Module &M) {
|
||||
|
||||
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
|
||||
// Don't print declarations for intrinsic functions.
|
||||
if (!I->getIntrinsicID() && I->getName() != "setjmp" &&
|
||||
if (!I->isIntrinsic() && I->getName() != "setjmp" &&
|
||||
I->getName() != "longjmp" && I->getName() != "_setjmp") {
|
||||
if (I->hasExternalWeakLinkage())
|
||||
Out << "extern ";
|
||||
|
@ -1586,7 +1586,7 @@ void MSILWriter::printExternals() {
|
||||
// Functions.
|
||||
for (I=ModulePtr->begin(),E=ModulePtr->end(); I!=E; ++I) {
|
||||
// Skip intrisics
|
||||
if (I->getIntrinsicID()) continue;
|
||||
if (I->isIntrinsic()) continue;
|
||||
if (I->isDeclaration()) {
|
||||
const Function* F = I;
|
||||
std::string Name = getConvModopt(F->getCallingConv())+getValueName(F);
|
||||
|
@ -284,7 +284,7 @@ void DAE::SurveyFunction(Function &F) {
|
||||
Liveness RetValLiveness = F.getReturnType() == Type::VoidTy ? Live : Dead;
|
||||
|
||||
if (!F.hasInternalLinkage() &&
|
||||
(!ShouldHackArguments() || F.getIntrinsicID()))
|
||||
(!ShouldHackArguments() || F.isIntrinsic()))
|
||||
FunctionIntrinsicallyLive = true;
|
||||
else
|
||||
for (Value::use_iterator I = F.use_begin(), E = F.use_end(); I != E; ++I) {
|
||||
|
@ -177,7 +177,7 @@ bool LowerGC::runOnFunction(Function &F) {
|
||||
for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E;)
|
||||
if (CallInst *CI = dyn_cast<CallInst>(II++)) {
|
||||
if (!CI->getCalledFunction() ||
|
||||
!CI->getCalledFunction()->getIntrinsicID())
|
||||
!CI->getCalledFunction()->isIntrinsic())
|
||||
NormalCalls.push_back(CI); // Remember all normal function calls.
|
||||
|
||||
if (Function *F = CI->getCalledFunction())
|
||||
|
@ -135,7 +135,7 @@ static bool MarkAliveBlocks(BasicBlock *BB,
|
||||
|
||||
// Turn invokes that call 'nounwind' functions into ordinary calls.
|
||||
if (InvokeInst *II = dyn_cast<InvokeInst>(BB->getTerminator()))
|
||||
if (II->paramHasAttr(0, ParamAttr::NoUnwind)) {
|
||||
if (II->isNoUnwind()) {
|
||||
ChangeToCall(II);
|
||||
Changed = true;
|
||||
}
|
||||
|
@ -69,13 +69,11 @@ static void HandleInlinedInvoke(InvokeInst *II, BasicBlock *FirstNewBlock,
|
||||
if (!isa<CallInst>(I)) continue;
|
||||
CallInst *CI = cast<CallInst>(I);
|
||||
|
||||
// If this is an intrinsic function call or an inline asm, don't
|
||||
// If this call cannot unwind or is an inline asm, don't
|
||||
// convert it to an invoke.
|
||||
if ((CI->getCalledFunction() &&
|
||||
CI->getCalledFunction()->getIntrinsicID()) ||
|
||||
isa<InlineAsm>(CI->getCalledValue()))
|
||||
if (CI->isNoUnwind() || isa<InlineAsm>(CI->getCalledValue()))
|
||||
continue;
|
||||
|
||||
|
||||
// Convert this function call into an invoke instruction.
|
||||
// First, split the basic block.
|
||||
BasicBlock *Split = BB->splitBasicBlock(CI, CI->getName()+".noexc");
|
||||
|
@ -20,7 +20,7 @@
|
||||
using namespace llvm;
|
||||
|
||||
|
||||
Function* llvm::UpgradeIntrinsicFunction(Function *F) {
|
||||
static Function* UpgradeIntrinsicFunction1(Function *F) {
|
||||
assert(F && "Illegal to upgrade a non-existent Function.");
|
||||
|
||||
// Get the Function's name.
|
||||
@ -119,6 +119,17 @@ Function* llvm::UpgradeIntrinsicFunction(Function *F) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Function* llvm::UpgradeIntrinsicFunction(Function *F) {
|
||||
Function *Upgraded = UpgradeIntrinsicFunction1(F);
|
||||
|
||||
// Upgrade intrinsic attributes. This does not change the function.
|
||||
if (Upgraded)
|
||||
F = Upgraded;
|
||||
if (unsigned id = F->getIntrinsicID(true))
|
||||
F->setParamAttrs(Intrinsic::getParamAttrs((Intrinsic::ID)id));
|
||||
return Upgraded;
|
||||
}
|
||||
|
||||
// UpgradeIntrinsicCall - Upgrade a call to an old intrinsic to be a call the
|
||||
// upgraded intrinsic. All argument and return casting must be provided in
|
||||
// order to seamlessly integrate with existing context.
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "llvm/Support/LeakDetector.h"
|
||||
#include "llvm/Support/ManagedStatic.h"
|
||||
#include "SymbolTableListTraitsImpl.h"
|
||||
#include "llvm/ADT/BitVector.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
using namespace llvm;
|
||||
|
||||
@ -435,12 +436,36 @@ const FunctionType *Intrinsic::getType(ID id, const Type **Tys,
|
||||
return FunctionType::get(ResultTy, ArgTys, IsVarArg);
|
||||
}
|
||||
|
||||
const ParamAttrsList *Intrinsic::getParamAttrs(ID id) {
|
||||
static const ParamAttrsList *IntrinsicAttributes[Intrinsic::num_intrinsics];
|
||||
|
||||
if (IntrinsicAttributes[id])
|
||||
return IntrinsicAttributes[id];
|
||||
|
||||
ParamAttrsVector Attrs;
|
||||
uint16_t Attr = ParamAttr::None;
|
||||
|
||||
#define GET_INTRINSIC_ATTRIBUTES
|
||||
#include "llvm/Intrinsics.gen"
|
||||
#undef GET_INTRINSIC_ATTRIBUTES
|
||||
|
||||
// Intrinsics cannot throw exceptions.
|
||||
Attr |= ParamAttr::NoUnwind;
|
||||
|
||||
Attrs.push_back(ParamAttrsWithIndex::get(0, Attr));
|
||||
IntrinsicAttributes[id] = ParamAttrsList::get(Attrs);
|
||||
return IntrinsicAttributes[id];
|
||||
}
|
||||
|
||||
Function *Intrinsic::getDeclaration(Module *M, ID id, const Type **Tys,
|
||||
unsigned numTys) {
|
||||
// There can never be multiple globals with the same name of different types,
|
||||
// because intrinsics must be a specific type.
|
||||
return cast<Function>(M->getOrInsertFunction(getName(id, Tys, numTys),
|
||||
getType(id, Tys, numTys)));
|
||||
// There can never be multiple globals with the same name of different types,
|
||||
// because intrinsics must be a specific type.
|
||||
Function *F =
|
||||
cast<Function>(M->getOrInsertFunction(getName(id, Tys, numTys),
|
||||
getType(id, Tys, numTys)));
|
||||
F->setParamAttrs(getParamAttrs(id));
|
||||
return F;
|
||||
}
|
||||
|
||||
Value *IntrinsicInst::StripPointerCasts(Value *Ptr) {
|
||||
|
@ -13,8 +13,8 @@
|
||||
|
||||
#include "llvm/Type.h"
|
||||
#include "llvm/Instructions.h"
|
||||
#include "llvm/IntrinsicInst.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/Support/CallSite.h"
|
||||
#include "llvm/Support/LeakDetector.h"
|
||||
using namespace llvm;
|
||||
|
||||
@ -197,31 +197,18 @@ bool Instruction::isSameOperationAs(Instruction *I) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
// IntrinsicOnlyReadsMemory - Return true if the specified intrinsic doesn't
|
||||
// have any side-effects or if it only reads memory.
|
||||
static bool IntrinsicOnlyReadsMemory(unsigned IntrinsicID) {
|
||||
#define GET_SIDE_EFFECT_INFO
|
||||
#include "llvm/Intrinsics.gen"
|
||||
#undef GET_SIDE_EFFECT_INFO
|
||||
return false;
|
||||
}
|
||||
|
||||
/// mayWriteToMemory - Return true if this instruction may modify memory.
|
||||
///
|
||||
bool Instruction::mayWriteToMemory() const {
|
||||
switch (getOpcode()) {
|
||||
default: return false;
|
||||
case Instruction::Free:
|
||||
case Instruction::Store:
|
||||
case Instruction::Invoke:
|
||||
case Instruction::Store:
|
||||
case Instruction::VAArg:
|
||||
return true;
|
||||
case Instruction::Call:
|
||||
if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(this)) {
|
||||
// If the intrinsic doesn't write memory, it is safe.
|
||||
return !IntrinsicOnlyReadsMemory(II->getIntrinsicID());
|
||||
}
|
||||
return true;
|
||||
return !cast<CallInst>(this)->onlyReadsMemory();
|
||||
case Instruction::Load:
|
||||
return cast<LoadInst>(this)->isVolatile();
|
||||
}
|
||||
|
@ -53,7 +53,18 @@ bool CallSite::paramHasAttr(uint16_t i, ParameterAttributes attr) const {
|
||||
else
|
||||
return cast<InvokeInst>(I)->paramHasAttr(i, attr);
|
||||
}
|
||||
|
||||
bool CallSite::doesNotAccessMemory() const {
|
||||
if (CallInst *CI = dyn_cast<CallInst>(I))
|
||||
return CI->doesNotAccessMemory();
|
||||
else
|
||||
return cast<InvokeInst>(I)->doesNotAccessMemory();
|
||||
}
|
||||
bool CallSite::onlyReadsMemory() const {
|
||||
if (CallInst *CI = dyn_cast<CallInst>(I))
|
||||
return CI->onlyReadsMemory();
|
||||
else
|
||||
return cast<InvokeInst>(I)->onlyReadsMemory();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -135,7 +135,7 @@ std::string Mangler::getValueName(const GlobalValue *GV, const char * Suffix) {
|
||||
// Name mangling occurs as follows:
|
||||
// - If V is an intrinsic function, do not change name at all
|
||||
// - Otherwise, mangling occurs if global collides with existing name.
|
||||
if (isa<Function>(GV) && cast<Function>(GV)->getIntrinsicID()) {
|
||||
if (isa<Function>(GV) && cast<Function>(GV)->isIntrinsic()) {
|
||||
Name = GV->getName(); // Is an intrinsic function
|
||||
} else if (!GV->hasName()) {
|
||||
// Must mangle the global into a unique ID.
|
||||
|
@ -685,7 +685,7 @@ static void CleanupAndPrepareModules(BugDriver &BD, Module *&Test,
|
||||
// Use the function we just added to get addresses of functions we need.
|
||||
for (Module::iterator F = Safe->begin(), E = Safe->end(); F != E; ++F) {
|
||||
if (F->isDeclaration() && !F->use_empty() && &*F != resolverFunc &&
|
||||
F->getIntrinsicID() == 0 /* ignore intrinsics */) {
|
||||
!F->isIntrinsic() /* ignore intrinsics */) {
|
||||
Function *TestFn = Test->getFunction(F->getName());
|
||||
|
||||
// Don't forward functions which are external in the test module too.
|
||||
|
@ -42,14 +42,8 @@ void IntrinsicEmitter::run(std::ostream &OS) {
|
||||
// Emit the intrinsic declaration generator.
|
||||
EmitGenerator(Ints, OS);
|
||||
|
||||
// Emit mod/ref info for each function.
|
||||
EmitModRefInfo(Ints, OS);
|
||||
|
||||
// Emit table of non-memory accessing intrinsics.
|
||||
EmitNoMemoryInfo(Ints, OS);
|
||||
|
||||
// Emit side effect info for each intrinsic.
|
||||
EmitSideEffectInfo(Ints, OS);
|
||||
// Emit the intrinsic parameter attributes.
|
||||
EmitAttributes(Ints, OS);
|
||||
|
||||
// Emit a list of intrinsics with corresponding GCC builtins.
|
||||
EmitGCCBuiltinList(Ints, OS);
|
||||
@ -297,30 +291,11 @@ void IntrinsicEmitter::EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints,
|
||||
OS << "#endif\n\n";
|
||||
}
|
||||
|
||||
void IntrinsicEmitter::EmitModRefInfo(const std::vector<CodeGenIntrinsic> &Ints,
|
||||
std::ostream &OS) {
|
||||
OS << "// BasicAliasAnalysis code.\n";
|
||||
OS << "#ifdef GET_MODREF_BEHAVIOR\n";
|
||||
for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
|
||||
switch (Ints[i].ModRef) {
|
||||
default: break;
|
||||
case CodeGenIntrinsic::NoMem:
|
||||
OS << " NoMemoryIntrinsics->set(Intrinsic::" << Ints[i].EnumName << ");\n";
|
||||
break;
|
||||
case CodeGenIntrinsic::ReadArgMem:
|
||||
case CodeGenIntrinsic::ReadMem:
|
||||
OS << " OnlyReadsMemoryIntrinsics->set(Intrinsic::" << Ints[i].EnumName << ");\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
OS << "#endif\n\n";
|
||||
}
|
||||
|
||||
void IntrinsicEmitter::
|
||||
EmitNoMemoryInfo(const std::vector<CodeGenIntrinsic> &Ints, std::ostream &OS) {
|
||||
OS << "// SelectionDAGIsel code.\n";
|
||||
OS << "#ifdef GET_NO_MEMORY_INTRINSICS\n";
|
||||
OS << " switch (IntrinsicID) {\n";
|
||||
EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, std::ostream &OS) {
|
||||
OS << "// Add parameter attributes that are not common to all intrinsics.\n";
|
||||
OS << "#ifdef GET_INTRINSIC_ATTRIBUTES\n";
|
||||
OS << " switch (id) {\n";
|
||||
OS << " default: break;\n";
|
||||
for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
|
||||
switch (Ints[i].ModRef) {
|
||||
@ -330,28 +305,19 @@ EmitNoMemoryInfo(const std::vector<CodeGenIntrinsic> &Ints, std::ostream &OS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
OS << " return true; // These intrinsics do not reference memory.\n";
|
||||
OS << " }\n";
|
||||
OS << "#endif\n\n";
|
||||
}
|
||||
|
||||
void IntrinsicEmitter::
|
||||
EmitSideEffectInfo(const std::vector<CodeGenIntrinsic> &Ints, std::ostream &OS){
|
||||
OS << "// Return true if doesn't access or only reads memory.\n";
|
||||
OS << "#ifdef GET_SIDE_EFFECT_INFO\n";
|
||||
OS << " switch (IntrinsicID) {\n";
|
||||
OS << " default: break;\n";
|
||||
OS << " Attr |= ParamAttr::ReadNone; // These do not access memory.\n";
|
||||
OS << " break;\n";
|
||||
for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
|
||||
switch (Ints[i].ModRef) {
|
||||
default: break;
|
||||
case CodeGenIntrinsic::NoMem:
|
||||
case CodeGenIntrinsic::ReadArgMem:
|
||||
case CodeGenIntrinsic::ReadMem:
|
||||
OS << " case Intrinsic::" << Ints[i].EnumName << ":\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
OS << " return true; // These intrinsics have no side effects.\n";
|
||||
OS << " Attr |= ParamAttr::ReadOnly; // These do not write memory.\n";
|
||||
OS << " break;\n";
|
||||
OS << " }\n";
|
||||
OS << "#endif\n\n";
|
||||
}
|
||||
|
@ -37,12 +37,8 @@ namespace llvm {
|
||||
std::ostream &OS);
|
||||
void EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints,
|
||||
std::ostream &OS);
|
||||
void EmitModRefInfo(const std::vector<CodeGenIntrinsic> &Ints,
|
||||
void EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints,
|
||||
std::ostream &OS);
|
||||
void EmitNoMemoryInfo(const std::vector<CodeGenIntrinsic> &Ints,
|
||||
std::ostream &OS);
|
||||
void EmitSideEffectInfo(const std::vector<CodeGenIntrinsic> &Ints,
|
||||
std::ostream &OS);
|
||||
void EmitGCCBuiltinList(const std::vector<CodeGenIntrinsic> &Ints,
|
||||
std::ostream &OS);
|
||||
void EmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints,
|
||||
|
Loading…
x
Reference in New Issue
Block a user