Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/TargetInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -1536,7 +1536,7 @@ class TargetInfo : public TransferrableTargetInfo,
/// which requires support for cpu_supports and cpu_is functionality.
bool supportsMultiVersioning() const {
return getTriple().isX86() || getTriple().isAArch64() ||
getTriple().isRISCV();
getTriple().isRISCV() || getTriple().isOSBinFormatXCOFF();
}

/// Identify whether this target supports IFuncs.
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/Sema/SemaPPC.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ class SemaPPC : public SemaBase {
// vector double vec_xxpermdi(vector double, vector double, int);
// vector short vec_xxsldwi(vector short, vector short, int);
bool BuiltinVSX(CallExpr *TheCall);

bool checkTargetClonesAttr(SmallVectorImpl<StringRef> &Params,
SmallVectorImpl<SourceLocation> &Locs,
SmallVectorImpl<SmallString<64>> &NewParams);
};
} // namespace clang

Expand Down
5 changes: 5 additions & 0 deletions clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14962,6 +14962,11 @@ void ASTContext::getFunctionFeatureMap(llvm::StringMap<bool> &FeatureMap,
StringRef VersionStr = TC->getFeatureStr(GD.getMultiVersionIndex());
if (VersionStr.starts_with("arch="))
TargetCPU = VersionStr.drop_front(sizeof("arch=") - 1);
else if (Target->getTriple().isOSAIX() &&
VersionStr.starts_with(
"cpu=")) // TODO make a function that extracts CPU from a
// feature string
TargetCPU = VersionStr.drop_front(sizeof("cpu=") - 1);
else if (VersionStr != "default")
Features.push_back((StringRef{"+"} + VersionStr).str());
Target->initFeatureMap(FeatureMap, getDiagnostics(), TargetCPU, Features);
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/AST/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,7 @@ add_clang_library(clangAST
# These generated headers are included transitively.
target_parser_gen
)
set_source_files_properties(
ASTContext.cpp
PROPERTIES COMPILE_FLAGS "-g -O0")

4 changes: 4 additions & 0 deletions clang/lib/Basic/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,7 @@ target_link_libraries(clangBasic
PRIVATE
${LLVM_ATOMIC_LIB}
)

set_source_files_properties(
TargetInfo.cpp Targets/X86.cpp Targets.cpp Targets/PPC.cpp
PROPERTIES COMPILE_FLAGS "-g -O0")
37 changes: 37 additions & 0 deletions clang/lib/Basic/Targets/PPC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,43 @@ void PPCTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
}
}

ParsedTargetAttr PPCTargetInfo::parseTargetAttr(StringRef Features) const {
ParsedTargetAttr Ret;
if (Features == "default")
return Ret;
SmallVector<StringRef, 1> AttrFeatures;
Features.split(AttrFeatures, ",");

// Grab the various features and prepend a "+" to turn on the feature to
// the backend and add them to our existing set of features.
for (auto &Feature : AttrFeatures) {
// Go ahead and trim whitespace rather than either erroring or
// accepting it weirdly.
Feature = Feature.trim();

// While we're here iterating check for a different target cpu.
if (Feature.starts_with("cpu=")) {
if (!Ret.CPU.empty())
Ret.Duplicate = "cpu=";
else
Ret.CPU = Feature.split("=").second.trim();
} else if (Feature.starts_with("tune=")) {
if (!Ret.Tune.empty())
Ret.Duplicate = "tune=";
else
Ret.Tune = Feature.split("=").second.trim();
} else if (Feature.starts_with("no-"))
Ret.Features.push_back("-" + Feature.split("-").second.str());
else
Ret.Features.push_back("+" + Feature.str());
}
return Ret;
}

llvm::APInt PPCTargetInfo::getFMVPriority(ArrayRef<StringRef> Features) const {
return llvm::APInt(32, Features.empty() ? 0 : 1);
}

// Make sure that registers are added in the correct array index which should be
// the DWARF number for PPC registers.
const char *const PPCTargetInfo::GCCRegNames[] = {
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Basic/Targets/PPC.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,10 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo {

bool supportsTargetAttributeTune() const override { return true; }

ParsedTargetAttr parseTargetAttr(StringRef Str) const override;

llvm::APInt getFMVPriority(ArrayRef<StringRef> Features) const override;

ArrayRef<const char *> getGCCRegNames() const override;

ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
Expand Down
73 changes: 73 additions & 0 deletions clang/lib/CodeGen/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -172,3 +172,76 @@ add_clang_library(clangCodeGen
clangLex
clangSerialization
)

set_source_files_properties(
ABIInfo.cpp
ABIInfoImpl.cpp
BackendUtil.cpp
CGAtomic.cpp
CGBlocks.cpp
CGBuiltin.cpp
CGCUDANV.cpp
CGCUDARuntime.cpp
CGCXX.cpp
CGCXXABI.cpp
CGCall.cpp
CGClass.cpp
CGCleanup.cpp
CGCoroutine.cpp
CGDebugInfo.cpp
CGDecl.cpp
CGDeclCXX.cpp
CGException.cpp
CGExpr.cpp
CGExprAgg.cpp
CGExprCXX.cpp
CGExprComplex.cpp
CGExprConstant.cpp
CGExprScalar.cpp
CGGPUBuiltin.cpp
CGHLSLRuntime.cpp
CGHLSLBuiltins.cpp
CGLoopInfo.cpp
CGNonTrivialStruct.cpp
CGObjC.cpp
CGObjCGNU.cpp
CGObjCMac.cpp
CGObjCRuntime.cpp
CGOpenCLRuntime.cpp
CGOpenMPRuntime.cpp
CGOpenMPRuntimeGPU.cpp
CGPointerAuth.cpp
CGRecordLayoutBuilder.cpp
CGStmt.cpp
CGStmtOpenMP.cpp
CGVTT.cpp
CGVTables.cpp
CodeGenABITypes.cpp
CodeGenAction.cpp
CodeGenFunction.cpp
CodeGenModule.cpp
CodeGenPGO.cpp
CodeGenSYCL.cpp
CodeGenTBAA.cpp
CodeGenTypes.cpp
ConstantInitBuilder.cpp
CoverageMappingGen.cpp
ItaniumCXXABI.cpp
HLSLBufferLayoutBuilder.cpp
LinkInModulesPass.cpp
MacroPPCallbacks.cpp
MicrosoftCXXABI.cpp
ModuleBuilder.cpp
ObjectFilePCHContainerWriter.cpp
PatternInit.cpp
SanitizerMetadata.cpp
TargetBuiltins/ARM.cpp
TargetBuiltins/PPC.cpp
TargetBuiltins/RISCV.cpp
TargetBuiltins/X86.cpp
TargetInfo.cpp
Targets/AArch64.cpp
Targets/ARM.cpp
Targets/PPC.cpp
Targets/X86.cpp
PROPERTIES COMPILE_FLAGS "-g -O0")
75 changes: 73 additions & 2 deletions clang/lib/CodeGen/CodeGenFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include "llvm/IR/Instruction.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IntrinsicsPowerPC.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/Support/CRC.h"
#include "llvm/Support/xxhash.h"
Expand Down Expand Up @@ -2994,10 +2995,80 @@ void CodeGenFunction::EmitMultiVersionResolver(
case llvm::Triple::riscv64:
EmitRISCVMultiVersionResolver(Resolver, Options);
return;

case llvm::Triple::ppc:
case llvm::Triple::ppc64:
if (getContext().getTargetInfo().getTriple().isOSAIX()) {
EmitPPCAIXMultiVersionResolver(Resolver, Options);
return;
}
[[fallthrough]];
default:
assert(false && "Only implemented for x86, AArch64 and RISC-V targets");
assert(false &&
"Only implemented for x86, AArch64, RISC-V, and PowerPC targets");
}
}

/*
* Desc_t *foo_desc = ppc_get_function_descriptor(&foo);
* if (foo_desc->addr == ppc_get_function_entry(&foo)) {
* FuncPtr fp = resolver();
* __c11_atomic_store((_Atomic FuncPtr *)&foo_desc->addr, fp, 0);
* }
* return ((int (*)(int)) foo_desc)(a);
*/
void CodeGenFunction::EmitPPCAIXMultiVersionResolver(
llvm::Function *Resolver, ArrayRef<FMVResolverOption> Options) {

llvm::PointerType *PtrTy = Builder.getPtrTy();
// entry:
llvm::BasicBlock *CurBlock = createBasicBlock("entry", Resolver);

SmallVector<std::pair<llvm::Value *, llvm::BasicBlock *>, 3> PhiArgs;
for (const FMVResolverOption &RO : Options) {
Builder.SetInsertPoint(CurBlock);
// The 'default' or 'generic' case.
if (!RO.Architecture && RO.Features.empty()) {
// if.default:
// %fmv.default = call ptr @getEntryPoint(ptr noundef @foo_default)
// br label %resolver_exit
assert(&RO == Options.end() - 1 &&
"Default or Generic case must be last");
Builder.CreateRet(RO.Function);
break;
}
// if.else_n:
// %is_version_n = __builtin_cpu_supports(version_n)
// br i1 %is_version_n, label %if.version_n, label %if.default
//
// if.version_n:
// %fmv.version.n = call ptr @getEntryPoint(ptr noundef @foo_version_n)
// br label %resolver_exit
assert(RO.Features.size() == 1 &&
"for now one feature requirement per version");
llvm::Value *Condition;
if (RO.Features[0].starts_with("cpu=")) {
Condition =
EmitPPCBuiltinCpu(Builtin::BI__builtin_cpu_is, Builder.getInt1Ty(),
RO.Features[0].split("=").second.trim());
} else {
Condition = EmitPPCBuiltinCpu(Builtin::BI__builtin_cpu_supports,
Builder.getInt1Ty(), RO.Features[0]);
}
llvm::BasicBlock *ThenBlock = createBasicBlock("if.version", Resolver);
CurBlock = createBasicBlock("if.else", Resolver);
Builder.CreateCondBr(Condition, ThenBlock, CurBlock);

Builder.SetInsertPoint(ThenBlock);
Builder.CreateRet(RO.Function);
}

// If no generic/default, emit an unreachable.
// Builder.SetInsertPoint(CurBlock);
// llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap);
// TrapCall->setDoesNotReturn();
// TrapCall->setDoesNotThrow();
// Builder.CreateUnreachable();
// Builder.ClearInsertionPoint();
}

void CodeGenFunction::EmitRISCVMultiVersionResolver(
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/CodeGen/CodeGenFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -4852,6 +4852,8 @@ class CodeGenFunction : public CodeGenTypeCache {

llvm::Value *BuildVector(ArrayRef<llvm::Value *> Ops);
llvm::Value *EmitX86BuiltinExpr(unsigned BuiltinID, const CallExpr *E);
llvm::Value *EmitPPCBuiltinCpu(unsigned BuiltinID, llvm::Type *ReturnType,
StringRef CPUStr);
llvm::Value *EmitPPCBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
llvm::Value *EmitAMDGPUBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
llvm::Value *EmitHLSLBuiltinExpr(unsigned BuiltinID, const CallExpr *E,
Expand Down Expand Up @@ -5519,6 +5521,9 @@ class CodeGenFunction : public CodeGenTypeCache {
void EmitRISCVMultiVersionResolver(llvm::Function *Resolver,
ArrayRef<FMVResolverOption> Options);

void EmitPPCAIXMultiVersionResolver(llvm::Function *Resolver,
ArrayRef<FMVResolverOption> Options);

private:
QualType getVarArgType(const Expr *Arg);

Expand Down
Loading