1 //===-- X86VZeroUpper.cpp - AVX vzeroupper instruction inserter -----------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the pass which inserts x86 AVX vzeroupper instructions
11 // before calls to SSE encoded functions. This avoids transition latency
12 // penalty when tranfering control between AVX encoded instructions and old
15 //===----------------------------------------------------------------------===//
17 #define DEBUG_TYPE "x86-codegen"
19 #include "X86InstrInfo.h"
20 #include "llvm/ADT/Statistic.h"
21 #include "llvm/CodeGen/MachineFunctionPass.h"
22 #include "llvm/CodeGen/MachineInstrBuilder.h"
23 #include "llvm/CodeGen/Passes.h"
24 #include "llvm/GlobalValue.h"
25 #include "llvm/Target/TargetInstrInfo.h"
28 STATISTIC(NumVZU, "Number of vzeroupper instructions inserted");
31 struct VZeroUpperInserter : public MachineFunctionPass {
33 VZeroUpperInserter() : MachineFunctionPass(ID) {}
35 virtual bool runOnMachineFunction(MachineFunction &MF);
37 bool processBasicBlock(MachineFunction &MF, MachineBasicBlock &MBB);
39 virtual const char *getPassName() const { return "X86 vzeroupper inserter";}
42 const TargetInstrInfo *TII; // Machine instruction info.
43 MachineBasicBlock *MBB; // Current basic block
45 char VZeroUpperInserter::ID = 0;
48 FunctionPass *llvm::createX86IssueVZeroUpperPass() {
49 return new VZeroUpperInserter();
52 /// runOnMachineFunction - Loop over all of the basic blocks, inserting
53 /// vzero upper instructions before function calls.
54 bool VZeroUpperInserter::runOnMachineFunction(MachineFunction &MF) {
55 TII = MF.getTarget().getInstrInfo();
58 // Process any unreachable blocks in arbitrary order now.
59 for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E; ++BB)
60 Changed |= processBasicBlock(MF, *BB);
65 bool isCallToModuleFn(const MachineInstr *MI) {
66 assert(MI->getDesc().isCall() && "Isn't a call instruction");
68 for (int i = 0, e = MI->getNumOperands(); i != e; ++i) {
69 const MachineOperand &MO = MI->getOperand(i);
74 const GlobalValue *GV = MO.getGlobal();
75 GlobalValue::LinkageTypes LT = GV->getLinkage();
76 if (GV->isInternalLinkage(LT) || GV->isPrivateLinkage(LT) ||
77 (GV->isExternalLinkage(LT) && !GV->isDeclaration()))
85 /// processBasicBlock - Loop over all of the instructions in the basic block,
86 /// inserting vzero upper instructions before function calls.
87 bool VZeroUpperInserter::processBasicBlock(MachineFunction &MF,
88 MachineBasicBlock &BB) {
92 for (MachineBasicBlock::iterator I = BB.begin(); I != BB.end(); ++I) {
94 DebugLoc dl = I->getDebugLoc();
96 // Insert a vzeroupper instruction before each control transfer
97 // to functions outside this module
98 if (MI->getDesc().isCall() && !isCallToModuleFn(MI)) {
99 BuildMI(*MBB, I, dl, TII->get(X86::VZEROUPPER));