|
14 | 14 | //===----------------------------------------------------------------------===//
|
15 | 15 |
|
16 | 16 | #include "llvm/IR/Attributes.h"
|
| 17 | +#include "llvm/IR/Function.h" |
17 | 18 | #include "AttributeImpl.h"
|
18 | 19 | #include "LLVMContextImpl.h"
|
19 | 20 | #include "llvm/ADT/STLExtras.h"
|
@@ -1407,3 +1408,80 @@ AttrBuilder AttributeFuncs::typeIncompatible(Type *Ty) {
|
1407 | 1408 |
|
1408 | 1409 | return Incompatible;
|
1409 | 1410 | }
|
| 1411 | + |
| 1412 | +template<typename AttrClass> |
| 1413 | +static bool isEqual(const Function &Caller, const Function &Callee) { |
| 1414 | + return Caller.getFnAttribute(AttrClass::Kind) == |
| 1415 | + Callee.getFnAttribute(AttrClass::Kind); |
| 1416 | +} |
| 1417 | + |
| 1418 | +/// \brief Compute the logical AND of the attributes of the caller and the |
| 1419 | +/// callee. |
| 1420 | +/// |
| 1421 | +/// This function sets the caller's attribute to false if the callee's attribute |
| 1422 | +/// is false. |
| 1423 | +template<typename AttrClass> |
| 1424 | +static void setAND(Function &Caller, const Function &Callee) { |
| 1425 | + if (AttrClass::isSet(Caller, AttrClass::Kind) && |
| 1426 | + !AttrClass::isSet(Callee, AttrClass::Kind)) |
| 1427 | + AttrClass::set(Caller, AttrClass::Kind, false); |
| 1428 | +} |
| 1429 | + |
| 1430 | +/// \brief Compute the logical OR of the attributes of the caller and the |
| 1431 | +/// callee. |
| 1432 | +/// |
| 1433 | +/// This function sets the caller's attribute to true if the callee's attribute |
| 1434 | +/// is true. |
| 1435 | +template<typename AttrClass> |
| 1436 | +static void setOR(Function &Caller, const Function &Callee) { |
| 1437 | + if (!AttrClass::isSet(Caller, AttrClass::Kind) && |
| 1438 | + AttrClass::isSet(Callee, AttrClass::Kind)) |
| 1439 | + AttrClass::set(Caller, AttrClass::Kind, true); |
| 1440 | +} |
| 1441 | + |
| 1442 | +/// \brief If the inlined function had a higher stack protection level than the |
| 1443 | +/// calling function, then bump up the caller's stack protection level. |
| 1444 | +static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) { |
| 1445 | + // If upgrading the SSP attribute, clear out the old SSP Attributes first. |
| 1446 | + // Having multiple SSP attributes doesn't actually hurt, but it adds useless |
| 1447 | + // clutter to the IR. |
| 1448 | + AttrBuilder B; |
| 1449 | + B.addAttribute(Attribute::StackProtect) |
| 1450 | + .addAttribute(Attribute::StackProtectStrong) |
| 1451 | + .addAttribute(Attribute::StackProtectReq); |
| 1452 | + AttributeSet OldSSPAttr = AttributeSet::get(Caller.getContext(), |
| 1453 | + AttributeSet::FunctionIndex, |
| 1454 | + B); |
| 1455 | + |
| 1456 | + if (Callee.hasFnAttribute(Attribute::SafeStack)) { |
| 1457 | + Caller.removeAttributes(AttributeSet::FunctionIndex, OldSSPAttr); |
| 1458 | + Caller.addFnAttr(Attribute::SafeStack); |
| 1459 | + } else if (Callee.hasFnAttribute(Attribute::StackProtectReq) && |
| 1460 | + !Caller.hasFnAttribute(Attribute::SafeStack)) { |
| 1461 | + Caller.removeAttributes(AttributeSet::FunctionIndex, OldSSPAttr); |
| 1462 | + Caller.addFnAttr(Attribute::StackProtectReq); |
| 1463 | + } else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) && |
| 1464 | + !Caller.hasFnAttribute(Attribute::SafeStack) && |
| 1465 | + !Caller.hasFnAttribute(Attribute::StackProtectReq)) { |
| 1466 | + Caller.removeAttributes(AttributeSet::FunctionIndex, OldSSPAttr); |
| 1467 | + Caller.addFnAttr(Attribute::StackProtectStrong); |
| 1468 | + } else if (Callee.hasFnAttribute(Attribute::StackProtect) && |
| 1469 | + !Caller.hasFnAttribute(Attribute::SafeStack) && |
| 1470 | + !Caller.hasFnAttribute(Attribute::StackProtectReq) && |
| 1471 | + !Caller.hasFnAttribute(Attribute::StackProtectStrong)) |
| 1472 | + Caller.addFnAttr(Attribute::StackProtect); |
| 1473 | +} |
| 1474 | + |
| 1475 | +#define GET_ATTR_COMPAT_FUNC |
| 1476 | +#include "AttributesCompatFunc.inc" |
| 1477 | + |
| 1478 | +bool AttributeFuncs::areInlineCompatible(const Function &Caller, |
| 1479 | + const Function &Callee) { |
| 1480 | + return hasCompatibleFnAttrs(Caller, Callee); |
| 1481 | +} |
| 1482 | + |
| 1483 | + |
| 1484 | +void AttributeFuncs::mergeAttributesForInlining(Function &Caller, |
| 1485 | + const Function &Callee) { |
| 1486 | + mergeFnAttrs(Caller, Callee); |
| 1487 | +} |
0 commit comments