Sure. Intel doesn't have to worry about performance to drive sales, they have no competition. The user upgrade market is quite small compared to the OEM market as well, so they can make more money by release only small upgrades and charging those who make the jump each time (or many of the times) out the yang.
The real money is in servers. There, Intel is in the same situation. They have no competition, so they only advance as much as they must to keep sales up and margins high.
While x86 gains are certainly not extremely simple, if you look at the changes Intel has made to the Core design to get us what we have today it is quite clear that they have only been doing what it takes to provide a small boost that will keep people interested and give the OEMs a more expensive CPU to purchase.
Every change is incremental and simple (for the most part). These are things we said Intel could do when Core 2s were out and about to increase performance (full AGUs, another ALU and FPU port, more scheduler slots, improved branch prediction, etc.) together with a few things that are more unique (reduced misprediction penalties).
Almost everything Intel has done has been to give the illusion of struggling to create more performance. They keep a GPU on these dies that will often go completely unused in higher end systems... they could EASILY take that off and use that die space to provide more performance. Either with two more cores or with wider cores.
The biggest hurdle to overcome is the microcode itself. When you add an ALU you have to know what you will have execute with it, same with an extra FPU pipe.
Want to know how to make it wildly faster? Easy:
8xALU/FPU pipes, 4x AGUs, 1x Store AGU, 1x Store Data, double the caches, double the instruction fetch, double the register pool, etc. Assign four logical cores to this core and use a single unified scheduler.
Now, each thread can potentially access 2x MUL, 2x DIV, 8x ADD, 8xLEA, 4x LOAD, 5xSTORE, 8x fop, etc... all at once.
You throw all of the instructions into the same cache, without any regard for which thread owns what, and you pull the instructions. When an instruction goes through decoding the register is chosen in the pool based on the thread to which the instruction belongs, and the data is loaded, and the instruction continues like nothing else is different.
This is completely doable, and would easily fit in the die space (it would actually be a bit smaller than two cores, but should perform just as well). With Intel's economies of scale this would probably even be affordable for those who *really* need high IPC.
Of course, this will NOT double IPC, as there's always a point in the code where you start working a bit too far out of the context and there are legacy concerns, but this is worth a good 50% single threaded boost.
You would then have Celerons and Pentiums with one super-fast core and two or more threads.