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,
 | |
|                                                       CallBase &Call) {
 | |
|   auto Index = IValue.Index;
 | |
|   auto *V = (Index == 0) ? &Call : Call.getArgOperand(Index - 1);
 | |
|   if (V->getType()->isPointerTy())
 | |
|     return InstantiatedValue{V, IValue.DerefLevel};
 | |
|   return None;
 | |
| }
 | |
| 
 | |
| Optional<InstantiatedRelation>
 | |
| instantiateExternalRelation(ExternalRelation ERelation, CallBase &Call) {
 | |
|   auto From = instantiateInterfaceValue(ERelation.From, Call);
 | |
|   if (!From)
 | |
|     return None;
 | |
|   auto To = instantiateInterfaceValue(ERelation.To, Call);
 | |
|   if (!To)
 | |
|     return None;
 | |
|   return InstantiatedRelation{*From, *To, ERelation.Offset};
 | |
| }
 | |
| 
 | |
| Optional<InstantiatedAttr> instantiateExternalAttribute(ExternalAttribute EAttr,
 | |
|                                                         CallBase &Call) {
 | |
|   auto Value = instantiateInterfaceValue(EAttr.IValue, Call);
 | |
|   if (!Value)
 | |
|     return None;
 | |
|   return InstantiatedAttr{*Value, EAttr.Attr};
 | |
| }
 | |
| }
 | |
| }
 |