@@ -9347,77 +9347,137 @@ struct AANoUndefCallSiteReturned final
9347
9347
void trackStatistics () const override { STATS_DECLTRACK_CSRET_ATTR (noundef) }
9348
9348
};
9349
9349
9350
- struct AACallEdgesFunction : public AACallEdges {
9351
- AACallEdgesFunction (const IRPosition &IRP, Attributor &A)
9352
- : AACallEdges(IRP, A) {}
9350
+ struct AACallEdgesImpl : public AACallEdges {
9351
+ AACallEdgesImpl (const IRPosition &IRP, Attributor &A) : AACallEdges(IRP, A) {}
9352
+
9353
+ virtual const SetVector<Function *> &getOptimisticEdges () const override {
9354
+ return CalledFunctions;
9355
+ }
9356
+
9357
+ virtual bool hasUnknownCallee () const override { return HasUnknownCallee; }
9358
+
9359
+ virtual bool hasNonAsmUnknownCallee () const override {
9360
+ return HasUnknownCalleeNonAsm;
9361
+ }
9362
+
9363
+ const std::string getAsStr () const override {
9364
+ return " CallEdges[" + std::to_string (HasUnknownCallee) + " ," +
9365
+ std::to_string (CalledFunctions.size ()) + " ]" ;
9366
+ }
9367
+
9368
+ void trackStatistics () const override {}
9369
+
9370
+ protected:
9371
+ void addCalledFunction (Function *Fn, ChangeStatus &Change) {
9372
+ if (CalledFunctions.insert (Fn)) {
9373
+ Change = ChangeStatus::CHANGED;
9374
+ LLVM_DEBUG (dbgs () << " [AACallEdges] New call edge: " << Fn->getName ()
9375
+ << " \n " );
9376
+ }
9377
+ }
9353
9378
9379
+ void setHasUnknownCallee (bool NonAsm, ChangeStatus &Change) {
9380
+ if (!HasUnknownCallee)
9381
+ Change = ChangeStatus::CHANGED;
9382
+ if (NonAsm && !HasUnknownCalleeNonAsm)
9383
+ Change = ChangeStatus::CHANGED;
9384
+ HasUnknownCalleeNonAsm |= NonAsm;
9385
+ HasUnknownCallee = true ;
9386
+ }
9387
+
9388
+ private:
9389
+ // / Optimistic set of functions that might be called by this position.
9390
+ SetVector<Function *> CalledFunctions;
9391
+
9392
+ // / Is there any call with a unknown callee.
9393
+ bool HasUnknownCallee = false ;
9394
+
9395
+ // / Is there any call with a unknown callee, excluding any inline asm.
9396
+ bool HasUnknownCalleeNonAsm = false ;
9397
+ };
9398
+
9399
+ struct AACallEdgesCallSite : public AACallEdgesImpl {
9400
+ AACallEdgesCallSite (const IRPosition &IRP, Attributor &A)
9401
+ : AACallEdgesImpl(IRP, A) {}
9354
9402
// / See AbstractAttribute::updateImpl(...).
9355
9403
ChangeStatus updateImpl (Attributor &A) override {
9356
9404
ChangeStatus Change = ChangeStatus::UNCHANGED;
9357
- bool OldHasUnknownCallee = HasUnknownCallee;
9358
- bool OldHasUnknownCalleeNonAsm = HasUnknownCalleeNonAsm;
9359
-
9360
- auto AddCalledFunction = [&](Function *Fn) {
9361
- if (CalledFunctions.insert (Fn)) {
9362
- Change = ChangeStatus::CHANGED;
9363
- LLVM_DEBUG (dbgs () << " [AACallEdges] New call edge: " << Fn->getName ()
9364
- << " \n " );
9365
- }
9366
- };
9367
9405
9368
9406
auto VisitValue = [&](Value &V, const Instruction *CtxI, bool &HasUnknown,
9369
9407
bool Stripped) -> bool {
9370
9408
if (Function *Fn = dyn_cast<Function>(&V)) {
9371
- AddCalledFunction (Fn);
9409
+ addCalledFunction (Fn, Change );
9372
9410
} else {
9373
9411
LLVM_DEBUG (dbgs () << " [AACallEdges] Unrecognized value: " << V << " \n " );
9374
- HasUnknown = true ;
9375
- HasUnknownCalleeNonAsm = true ;
9412
+ setHasUnknownCallee (true , Change);
9376
9413
}
9377
9414
9378
9415
// Explore all values.
9379
9416
return true ;
9380
9417
};
9381
9418
9382
9419
// Process any value that we might call.
9383
- auto ProcessCalledOperand = [&](Value *V, Instruction *Ctx) {
9420
+ auto ProcessCalledOperand = [&](Value *V) {
9421
+ bool DummyValue = false ;
9384
9422
if (!genericValueTraversal<bool >(A, IRPosition::value (*V), *this ,
9385
- HasUnknownCallee , VisitValue, nullptr ,
9423
+ DummyValue , VisitValue, nullptr ,
9386
9424
false )) {
9387
9425
// If we haven't gone through all values, assume that there are unknown
9388
9426
// callees.
9389
- HasUnknownCallee = true ;
9390
- HasUnknownCalleeNonAsm = true ;
9427
+ setHasUnknownCallee (true , Change);
9391
9428
}
9392
9429
};
9393
9430
9394
- auto ProcessCallInst = [&](Instruction &Inst) {
9395
- CallBase &CB = static_cast <CallBase &>(Inst);
9396
- if (CB.isInlineAsm ()) {
9397
- HasUnknownCallee = true ;
9398
- return true ;
9399
- }
9431
+ CallBase *CB = static_cast <CallBase *>(getCtxI ());
9400
9432
9401
- // Process callee metadata if available.
9402
- if (auto *MD = Inst.getMetadata (LLVMContext::MD_callees)) {
9403
- for (auto &Op : MD->operands ()) {
9404
- Function *Callee = mdconst::extract_or_null<Function>(Op);
9405
- if (Callee)
9406
- AddCalledFunction (Callee);
9407
- }
9408
- // Callees metadata grantees that the called function is one of its
9409
- // operands, So we are done.
9410
- return true ;
9433
+ if (CB->isInlineAsm ()) {
9434
+ setHasUnknownCallee (false , Change);
9435
+ return Change;
9436
+ }
9437
+
9438
+ // Process callee metadata if available.
9439
+ if (auto *MD = getCtxI ()->getMetadata (LLVMContext::MD_callees)) {
9440
+ for (auto &Op : MD->operands ()) {
9441
+ Function *Callee = mdconst::extract_or_null<Function>(Op);
9442
+ if (Callee)
9443
+ addCalledFunction (Callee, Change);
9411
9444
}
9445
+ return Change;
9446
+ }
9412
9447
9413
- // The most simple case.
9414
- ProcessCalledOperand (CB. getCalledOperand (), &Inst );
9448
+ // The most simple case.
9449
+ ProcessCalledOperand (CB-> getCalledOperand ());
9415
9450
9416
- // Process callback functions.
9417
- SmallVector<const Use *, 4u > CallbackUses;
9418
- AbstractCallSite::getCallbackUses (CB, CallbackUses);
9419
- for (const Use *U : CallbackUses)
9420
- ProcessCalledOperand (U->get (), &Inst);
9451
+ // Process callback functions.
9452
+ SmallVector<const Use *, 4u > CallbackUses;
9453
+ AbstractCallSite::getCallbackUses (*CB, CallbackUses);
9454
+ for (const Use *U : CallbackUses)
9455
+ ProcessCalledOperand (U->get ());
9456
+
9457
+ return Change;
9458
+ }
9459
+ };
9460
+
9461
+ struct AACallEdgesFunction : public AACallEdgesImpl {
9462
+ AACallEdgesFunction (const IRPosition &IRP, Attributor &A)
9463
+ : AACallEdgesImpl(IRP, A) {}
9464
+
9465
+ // / See AbstractAttribute::updateImpl(...).
9466
+ ChangeStatus updateImpl (Attributor &A) override {
9467
+ ChangeStatus Change = ChangeStatus::UNCHANGED;
9468
+
9469
+ auto ProcessCallInst = [&](Instruction &Inst) {
9470
+ CallBase &CB = static_cast <CallBase &>(Inst);
9471
+
9472
+ auto &CBEdges = A.getAAFor <AACallEdges>(
9473
+ *this , IRPosition::callsite_function (CB), DepClassTy::REQUIRED);
9474
+ if (CBEdges.hasNonAsmUnknownCallee ())
9475
+ setHasUnknownCallee (false , Change);
9476
+ if (CBEdges.hasUnknownCallee ())
9477
+ setHasUnknownCallee (true , Change);
9478
+
9479
+ for (Function *F : CBEdges.getOptimisticEdges ())
9480
+ addCalledFunction (F, Change);
9421
9481
9422
9482
return true ;
9423
9483
};
@@ -9428,43 +9488,11 @@ struct AACallEdgesFunction : public AACallEdges {
9428
9488
UsedAssumedInformation)) {
9429
9489
// If we haven't looked at all call like instructions, assume that there
9430
9490
// are unknown callees.
9431
- HasUnknownCallee = true ;
9432
- HasUnknownCalleeNonAsm = true ;
9491
+ setHasUnknownCallee (true , Change);
9433
9492
}
9434
9493
9435
- // Track changes.
9436
- if (OldHasUnknownCallee != HasUnknownCallee ||
9437
- OldHasUnknownCalleeNonAsm != HasUnknownCalleeNonAsm)
9438
- Change = ChangeStatus::CHANGED;
9439
-
9440
9494
return Change;
9441
9495
}
9442
-
9443
- virtual const SetVector<Function *> &getOptimisticEdges () const override {
9444
- return CalledFunctions;
9445
- };
9446
-
9447
- virtual bool hasUnknownCallee () const override { return HasUnknownCallee; }
9448
-
9449
- virtual bool hasNonAsmUnknownCallee () const override {
9450
- return HasUnknownCalleeNonAsm;
9451
- }
9452
-
9453
- const std::string getAsStr () const override {
9454
- return " CallEdges[" + std::to_string (HasUnknownCallee) + " ," +
9455
- std::to_string (CalledFunctions.size ()) + " ]" ;
9456
- }
9457
-
9458
- void trackStatistics () const override {}
9459
-
9460
- // / Optimistic set of functions that might be called by this function.
9461
- SetVector<Function *> CalledFunctions;
9462
-
9463
- // / Is there any call with a unknown callee.
9464
- bool HasUnknownCallee = false ;
9465
-
9466
- // / Is there any call with a unknown callee, excluding any inline asm.
9467
- bool HasUnknownCalleeNonAsm = false ;
9468
9496
};
9469
9497
9470
9498
struct AAFunctionReachabilityFunction : public AAFunctionReachability {
@@ -9715,6 +9743,7 @@ CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAWillReturn)
9715
9743
CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION (AANoReturn)
9716
9744
CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION (AAReturnedValues)
9717
9745
CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION (AAMemoryLocation)
9746
+ CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION (AACallEdges)
9718
9747
9719
9748
CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION (AANonNull)
9720
9749
CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION (AANoAlias)
@@ -9734,7 +9763,6 @@ CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoFree)
9734
9763
CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION (AAHeapToStack)
9735
9764
CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION (AAReachability)
9736
9765
CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION (AAUndefinedBehavior)
9737
- CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION (AACallEdges)
9738
9766
CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION (AAFunctionReachability)
9739
9767
9740
9768
CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION (AAMemoryBehavior)
0 commit comments