104 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			104 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C++
		
	
	
	
#include "AliasAnalysisSummary.h"
 | 
						|
#include "llvm/IR/Argument.h"
 | 
						|
#include "llvm/IR/Type.h"
 | 
						|
#include "llvm/Support/Compiler.h"
 | 
						|
 | 
						|
namespace llvm {
 | 
						|
namespace cflaa {
 | 
						|
 | 
						|
namespace {
 | 
						|
const unsigned AttrEscapedIndex = 0;
 | 
						|
const unsigned AttrUnknownIndex = 1;
 | 
						|
const unsigned AttrGlobalIndex = 2;
 | 
						|
const unsigned AttrCallerIndex = 3;
 | 
						|
const unsigned AttrFirstArgIndex = 4;
 | 
						|
const unsigned AttrLastArgIndex = NumAliasAttrs;
 | 
						|
const unsigned AttrMaxNumArgs = AttrLastArgIndex - AttrFirstArgIndex;
 | 
						|
 | 
						|
// It would be *slightly* prettier if we changed these to AliasAttrs, but it
 | 
						|
// seems that both GCC and MSVC emit dynamic initializers for const bitsets.
 | 
						|
using AliasAttr = unsigned;
 | 
						|
const AliasAttr AttrNone = 0;
 | 
						|
const AliasAttr AttrEscaped = 1 << AttrEscapedIndex;
 | 
						|
const AliasAttr AttrUnknown = 1 << AttrUnknownIndex;
 | 
						|
const AliasAttr AttrGlobal = 1 << AttrGlobalIndex;
 | 
						|
const AliasAttr AttrCaller = 1 << AttrCallerIndex;
 | 
						|
const AliasAttr ExternalAttrMask = AttrEscaped | AttrUnknown | AttrGlobal;
 | 
						|
}
 | 
						|
 | 
						|
AliasAttrs getAttrNone() { return AttrNone; }
 | 
						|
 | 
						|
AliasAttrs getAttrUnknown() { return AttrUnknown; }
 | 
						|
bool hasUnknownAttr(AliasAttrs Attr) { return Attr.test(AttrUnknownIndex); }
 | 
						|
 | 
						|
AliasAttrs getAttrCaller() { return AttrCaller; }
 | 
						|
bool hasCallerAttr(AliasAttrs Attr) { return Attr.test(AttrCaller); }
 | 
						|
bool hasUnknownOrCallerAttr(AliasAttrs Attr) {
 | 
						|
  return Attr.test(AttrUnknownIndex) || Attr.test(AttrCallerIndex);
 | 
						|
}
 | 
						|
 | 
						|
AliasAttrs getAttrEscaped() { return AttrEscaped; }
 | 
						|
bool hasEscapedAttr(AliasAttrs Attr) { return Attr.test(AttrEscapedIndex); }
 | 
						|
 | 
						|
static AliasAttr argNumberToAttr(unsigned ArgNum) {
 | 
						|
  if (ArgNum >= AttrMaxNumArgs)
 | 
						|
    return AttrUnknown;
 | 
						|
  // N.B. MSVC complains if we use `1U` here, since AliasAttr' ctor takes
 | 
						|
  // an unsigned long long.
 | 
						|
  return AliasAttr(1ULL << (ArgNum + AttrFirstArgIndex));
 | 
						|
}
 | 
						|
 | 
						|
AliasAttrs getGlobalOrArgAttrFromValue(const Value &Val) {
 | 
						|
  if (isa<GlobalValue>(Val))
 | 
						|
    return AttrGlobal;
 | 
						|
 | 
						|
  if (auto *Arg = dyn_cast<Argument>(&Val))
 | 
						|
    // Only pointer arguments should have the argument attribute,
 | 
						|
    // because things can't escape through scalars without us seeing a
 | 
						|
    // cast, and thus, interaction with them doesn't matter.
 | 
						|
    if (!Arg->hasNoAliasAttr() && Arg->getType()->isPointerTy())
 | 
						|
      return argNumberToAttr(Arg->getArgNo());
 | 
						|
  return AttrNone;
 | 
						|
}
 | 
						|
 | 
						|
bool isGlobalOrArgAttr(AliasAttrs Attr) {
 | 
						|
  return Attr.reset(AttrEscapedIndex)
 | 
						|
      .reset(AttrUnknownIndex)
 | 
						|
      .reset(AttrCallerIndex)
 | 
						|
      .any();
 | 
						|
}
 | 
						|
 | 
						|
AliasAttrs getExternallyVisibleAttrs(AliasAttrs Attr) {
 | 
						|
  return Attr & AliasAttrs(ExternalAttrMask);
 | 
						|
}
 | 
						|
 | 
						|
Optional<InstantiatedValue> instantiateInterfaceValue(InterfaceValue IValue,
 | 
						|
                                                      CallSite CS) {
 | 
						|
  auto Index = IValue.Index;
 | 
						|
  auto Value = (Index == 0) ? CS.getInstruction() : CS.getArgument(Index - 1);
 | 
						|
  if (Value->getType()->isPointerTy())
 | 
						|
    return InstantiatedValue{Value, IValue.DerefLevel};
 | 
						|
  return None;
 | 
						|
}
 | 
						|
 | 
						|
Optional<InstantiatedRelation>
 | 
						|
instantiateExternalRelation(ExternalRelation ERelation, CallSite CS) {
 | 
						|
  auto From = instantiateInterfaceValue(ERelation.From, CS);
 | 
						|
  if (!From)
 | 
						|
    return None;
 | 
						|
  auto To = instantiateInterfaceValue(ERelation.To, CS);
 | 
						|
  if (!To)
 | 
						|
    return None;
 | 
						|
  return InstantiatedRelation{*From, *To, ERelation.Offset};
 | 
						|
}
 | 
						|
 | 
						|
Optional<InstantiatedAttr> instantiateExternalAttribute(ExternalAttribute EAttr,
 | 
						|
                                                        CallSite CS) {
 | 
						|
  auto Value = instantiateInterfaceValue(EAttr.IValue, CS);
 | 
						|
  if (!Value)
 | 
						|
    return None;
 | 
						|
  return InstantiatedAttr{*Value, EAttr.Attr};
 | 
						|
}
 | 
						|
}
 | 
						|
}
 |