Changeset View
Changeset View
Standalone View
Standalone View
lib/Transforms/Utils/CodeExtractor.cpp
Show First 20 Lines • Show All 614 Lines • ▼ Show 20 Lines | Function *CodeExtractor::constructFunction(const ValueSet &inputs, | ||||
// If the old function is no-throw, so is the new one. | // If the old function is no-throw, so is the new one. | ||||
if (oldFunction->doesNotThrow()) | if (oldFunction->doesNotThrow()) | ||||
newFunction->setDoesNotThrow(); | newFunction->setDoesNotThrow(); | ||||
// Inherit the uwtable attribute if we need to. | // Inherit the uwtable attribute if we need to. | ||||
if (oldFunction->hasUWTable()) | if (oldFunction->hasUWTable()) | ||||
newFunction->setHasUWTable(); | newFunction->setHasUWTable(); | ||||
// Inherit all of the target dependent attributes. | // Inherit all of the target dependent attributes and white-listed | ||||
// target independent attributes. | |||||
// (e.g. If the extracted region contains a call to an x86.sse | // (e.g. If the extracted region contains a call to an x86.sse | ||||
// instruction we need to make sure that the extracted region has the | // instruction we need to make sure that the extracted region has the | ||||
// "target-features" attribute allowing it to be lowered. | // "target-features" attribute allowing it to be lowered. | ||||
// FIXME: This should be changed to check to see if a specific | // FIXME: This should be changed to check to see if a specific | ||||
// attribute can not be inherited. | // attribute can not be inherited. | ||||
AttrBuilder AB(oldFunction->getAttributes().getFnAttributes()); | for (const auto &Attr : oldFunction->getAttributes().getFnAttributes()) { | ||||
for (const auto &Attr : AB.td_attrs()) | if (Attr.isStringAttribute()) { | ||||
newFunction->addFnAttr(Attr.first, Attr.second); | if (Attr.getKindAsString() == "thunk") | ||||
continue; | |||||
} else | |||||
switch (Attr.getKindAsEnum()) { | |||||
// Those attributes cannot be propagated safely. Explicitly list them | |||||
efriedma: Could we explicitly list out all the attributes here, so the compiler will warn if a new… | |||||
// here so we get a warning if new attributes are added. This list also | |||||
// includes non-function attributes. | |||||
case Attribute::Alignment: | |||||
case Attribute::AllocSize: | |||||
case Attribute::ArgMemOnly: | |||||
case Attribute::Builtin: | |||||
case Attribute::ByVal: | |||||
case Attribute::Convergent: | |||||
Not sure about propagating JumpTable and Naked. (Granted, we probably shouldn't be extracting code from Naked functions anyway.) efriedma: Not sure about propagating JumpTable and Naked. (Granted, we probably shouldn't be extracting… | |||||
case Attribute::Dereferenceable: | |||||
case Attribute::DereferenceableOrNull: | |||||
case Attribute::InAlloca: | |||||
case Attribute::InReg: | |||||
case Attribute::InaccessibleMemOnly: | |||||
case Attribute::InaccessibleMemOrArgMemOnly: | |||||
case Attribute::JumpTable: | |||||
case Attribute::Naked: | |||||
case Attribute::Nest: | |||||
case Attribute::NoAlias: | |||||
case Attribute::NoBuiltin: | |||||
case Attribute::NoCapture: | |||||
case Attribute::NoReturn: | |||||
case Attribute::None: | |||||
case Attribute::NonNull: | |||||
case Attribute::ReadNone: | |||||
case Attribute::ReadOnly: | |||||
case Attribute::Returned: | |||||
case Attribute::ReturnsTwice: | |||||
case Attribute::SExt: | |||||
case Attribute::Speculatable: | |||||
case Attribute::StackAlignment: | |||||
case Attribute::StructRet: | |||||
case Attribute::SwiftError: | |||||
case Attribute::SwiftSelf: | |||||
case Attribute::WriteOnly: | |||||
case Attribute::ZExt: | |||||
case Attribute::EndAttrKinds: | |||||
continue; | |||||
// Those attributes should be safe to propagate to the extracted function. | |||||
case Attribute::AlwaysInline: | |||||
case Attribute::Cold: | |||||
case Attribute::NoRecurse: | |||||
case Attribute::InlineHint: | |||||
case Attribute::MinSize: | |||||
case Attribute::NoDuplicate: | |||||
case Attribute::NoImplicitFloat: | |||||
case Attribute::NoInline: | |||||
case Attribute::NonLazyBind: | |||||
case Attribute::NoRedZone: | |||||
case Attribute::NoUnwind: | |||||
case Attribute::OptimizeNone: | |||||
case Attribute::OptimizeForSize: | |||||
case Attribute::SafeStack: | |||||
case Attribute::SanitizeAddress: | |||||
case Attribute::SanitizeMemory: | |||||
case Attribute::SanitizeThread: | |||||
case Attribute::SanitizeHWAddress: | |||||
case Attribute::StackProtect: | |||||
case Attribute::StackProtectReq: | |||||
case Attribute::StackProtectStrong: | |||||
case Attribute::StrictFP: | |||||
case Attribute::UWTable: | |||||
break; | |||||
} | |||||
newFunction->addFnAttr(Attr); | |||||
} | |||||
newFunction->getBasicBlockList().push_back(newRootNode); | newFunction->getBasicBlockList().push_back(newRootNode); | ||||
// Create an iterator to name all of the arguments we inserted. | // Create an iterator to name all of the arguments we inserted. | ||||
Function::arg_iterator AI = newFunction->arg_begin(); | Function::arg_iterator AI = newFunction->arg_begin(); | ||||
// Rewrite all users of the inputs in the extracted region to use the | // Rewrite all users of the inputs in the extracted region to use the | ||||
// arguments (or appropriate addressing into struct) instead. | // arguments (or appropriate addressing into struct) instead. | ||||
for (unsigned i = 0, e = inputs.size(); i != e; ++i) { | for (unsigned i = 0, e = inputs.size(); i != e; ++i) { | ||||
▲ Show 20 Lines • Show All 505 Lines • Show Last 20 Lines |
Could we explicitly list out all the attributes here, so the compiler will warn if a new attribute gets added?